<?php
/**
* 
*/
class ElephantajiangModel extends BaseModel
{
	
	const LIST_KEY = 'roomlist';
	const PLAYING_KEY = "room_playing_list";
	const INFO_KEY = 'room:';
	const PLAYER_ORDER ='player_order::';
	const MAX_POS = 4;//允许参加的人数
	const DEFAULT_POINT = 10000;
	const MAX_POINT = 4;
	const MAX_STEP = 5;
	const TIMER_DELAY = 16;//后端延迟16s
	
	//玩家状态
	const STATE_NONE = 0;//未开始
	const STATE_READY = 1;//准备
	const STATE_PLAYING = 2;//进行中
	
	private $mUser = null;
	private $id	= null;//房间号码
	private $uid = null;//用户标识
	private $info = null;
	private $log=null;
	const SUM="sum:";
	public function __construct($mUser, $id = null)
	{	
		$this->mUser = $mUser;
		$this->id = $id;
		$this->uid = $this->mUser->getUid();
		$this->redis = RedisDB::factory('game');
		$logHandler= new CLogFileHandler("./logs/".date('Y-m-d').'.log');
		$log = Log::Init($logHandler, 15);
	}
	public function getId()
	{
		return $this->id;
	}
		
	public function getInfo()
	{	

		if($this->info === null){
			$info = $this->redis->hGetAll(self::INFO_KEY . $this->id);
			if(!$info){
				$this->_error='没有找到房间';
				return false;
			}
			
			for($i = 1; $i <= self::MAX_POS; ++$i){
				$seatkey = "seat$i";
				//$info['seat'.$i]='';
				//$this->redis->hMset(self::INFO_KEY . $this->id,$info );
				if(isset($info[$seatkey])){
					$info[$seatkey] = json_decode($info[$seatkey], true);
				}
			}
			
			//coin list
			//$info['coins'] = empty($info['coins']) ? array() : json_decode($info['coins'], true);
			
			$this->info = $info;
		}
		
		return $this->info;
	}
	public function getInfoEx()
	{
		$info = $this->getInfo();
		$users = array();
		$myseatid = 0;
		for($i = 1; $i <= self::MAX_POS; ++$i){
			$seatKey = "seat$i";
			if(empty($info[$seatKey])){
				continue;
			}
			
			$seat = $info[$seatKey];
			$mUser = new UserModel($seat['uid']);
			$user = $mUser->getInfo();
			$seat['name'] = $user['nickname'];
			$seat['avatar'] = $user['headimgurl'];
			$seat['offline'] = isset($info["exit$i"]);
			
			//myself
			if($seat['uid'] == $this->uid){
				$myseatid = $seat['seatid'];
				$seat['offline'] = 0;
				//$info['cards'] = empty($seat['look']) ? array() : $seat['cards'];
			}
			
			$users[] = $seat;
		}
		
		$info['seatid'] = $myseatid;
		$info['users'] = $users;
		
		//send online state
		$exitkey = "exit{$myseatid}";
		if(isset($info[$exitkey])){
			$this->redis->hDel(self::INFO_KEY . $this->id, $exitkey);
			Socket::sendToChannel("game-{$this->id}", "Elephant", "online", array(
				'seatid' => $myseatid,
			));
		}
		
		//join
		Socket::getRouter()->addChannel("game-{$this->id}", SESSIONID);
		
		return $info;
	}
	//获取头像信息
	public function information($seatid){
		$room = $this->getInfo();
		$seatkey = "seat".$seatid;
		$myseatinfo = $room[$seatkey];
		$uid =$myseatinfo['uid'];
		$mUser=new UserModel($uid);
		$user = $mUser->getInfo();
		$mMatch =new MatchModel($user['uid']);
		$s=$mMatch->getMacth();
		$out =isset($s['list'])?json_decode($s['list']):'';
		$total =0;
		$victory= 0;
		$escape = 0;
		if(is_array($out)){
			foreach($out as $key=>$v){
			if($v->roomid!=$this->id) continue;
				$total++;
				if($v->score>0){
					$victory++;
				}
			}
		}
		
		$information =array(
				'headimgurl'=>$user['headimgurl'],
				'nickname'=>$user['nickname'],
				'match'=>$total,
				'victory'=>$victory,
				'escape'=>$escape,
			);

		return $information;
	}
	//离线事件
	public function offline($seatid,$user)
	{	
		$leave_info[]=  array(
				'uid'=>$user['uid'],
				'nickname'=>$user['nickname'],
				'headimgurl'=>$user['headimgurl'],
				'seatid'=>$user['seatid'],
			);
		//file_put_contents('./logs/leve.txt', json_encode($leave_info));
		$room = $this->getInfo();
		$mUser = new UserModel($user['uid']);
		//$user=$mUser->getInfo();
		//游戏未开始释放人和座位
		$state =isset($room['state'])&&$room['state']?$state:0;
		if(!$state){
			$seatkey="seat".$seatid;
			unset($room[$seatkey]);
			$this->redis->hMSet(self::INFO_KEY . $this->id, $room);
			//清空座位和房间
			
			$user['seatid']='';
			$user['roomid']='';
			$mUser->save($user);
		}

		$this->redis->hSet(self::INFO_KEY . $this->id, "exit{$seatid}", 1);
		$seatall  = array();
		for($i = 1; $i <= self::MAX_POS; ++$i){
			$seatkey ="seat".$i;
			if($seatid==$i){
				if(isset($room[$seatkey])){
					$seatall[$i] =$room[$seatkey];
				}
				
			}
			
		}
		$seats = json_encode($seatall);
		//file_put_contents('./logs/leve.txt', json_encode($leave_info));
		Socket::sendToChannel("game-{$this->id}", "Elephant", "offline", array(
			'leave_info'=>$leave_info,
			'seats'=>$seats,
			'seatid'=>$seatid,
		));
	}
	public function getUidBySeatid($seatid){
		$seatkey ="seat".$seatid;
		$uid = $this->redis->hGet(self::INFO_KEY . $this->id,$seatkey);
		return $uid;
	}
	public function expression($emoji,$type,$receive_seatid,$money){
		$uid = $this->mUser->getUid();
		$room = $this->getInfo();
		$user = $this->mUser->getInfo();
		$myseatid = $user['seatid'];
		if($type=="other" && $money){
			$user= $user['gold']-$money? $user['gold']-$money:0;
			$this->mUser->save($user);
		}
		Socket::sendToChannel("game-{$this->id}", "Elephant", "expression", array(
				'seatid' => $myseatid,
				'type' => $type,
				'emoji'=>$emoji,
				'receive_seatid'=>$receive_seatid,
			));
		return true;
	}
	public function seat($seatid){
		$uid = $this->mUser->getUid();
		$log =new LogModel($this->id,$uid);
		$thisRoomUid = $log->getUidByRoom();
		if(is_array($thisRoomUid)&&$thisRoomUid){
			$thisRoomUid[]=$uid;
		}else{
			$thisRoomUid[]=$uid;
		}
		if(!$log->isExist()){
			$mUser =new UserModel($uid);
			$user =$mUser->getInfo();
			$user['gold'] =$user['gold']>=100?$user['gold']-100:$user['gold'];
			$mUser->save($user);
			$log ->save($thisRoomUid);
		}
		
		$info = $this->getInfo();
		$pos = 0;
		$seatKey = "seat$seatid";
		if(!empty($info[$seatKey])){
			$this->_error ='坐位已经占用了';
			return false;
		}
			
		if(!$this->redis->hSetNx(self::INFO_KEY . $this->id, $seatKey, $uid)){
			$this->_error = '坐下失败';
			return false;
		}
		$pos = $seatid;
		//如果之前已经做过了就要把原来的位置去了
		$roomInfo = $this->redis->hGetAll(self::INFO_KEY . $this->id);//当前房间的信息
		//获取房主信息
		if($roomInfo['owner']){
			$owner =intval($roomInfo['owner']);
			$mUser = new UserModel($owner);
			$owner_user = $mUser->getInfo();
			$owner_nickname=$owner_user['nickname'];
			$owner_headimgurl=$owner_user['headimgurl'];
		}

		$this->clearMyseat($roomInfo,$uid);
		// if(isset($roomInfo[$seatKey]) && $roomInfo[$seatKey]){
		// 	$this->redis->hDel(self::INFO_KEY . $this->id,$seatKey);
		// }
		
		if($pos){
			$seat = array(
				'uid' => $uid,
				'seatid' => $pos,
				'state' => self::STATE_NONE,
				'point' => 0,
			);
			$this->redis->hSet(self::INFO_KEY . $this->id, $seatKey, json_encode($seat));
			$this->mUser->save(array(
				'roomid' => $this->id,
				'seatid' => $pos,
			));
				
			$room_info[] =array(
				'owner'=>$roomInfo['owner'],
	            'double'=>$roomInfo['double'],
	            'roomid' => $this->id,
	            'time_way'=>$roomInfo['time_way'],
	            'time_key'=>$roomInfo['time_value'],
	            'create_time'=>$roomInfo['time'],
	            'system_time' => time(),
	            'present_quan'=>$roomInfo['present_quan'],
			);
			if($roomInfo['owner']){
				$userModel =new UserModel($roomInfo['owner']);
				$owner_users= $userModel->getInfo();
				$owner_info[]=array(
						'uid'=>$roomInfo['owner'],
			            'seatid'=>$owner_users['seatid'],
			            'nickname'=>$owner_users['nickname'],
			            'headimgurl'=>$owner_users['headimgurl'],
					);
			}
			for($i=1;$i<=4;$i++){
				$info =$this->redis->hGetAll(self::INFO_KEY . $this->id);
				$seatkey ="seat".$i;
				$cur_seat_info=array();
				if(isset($info[$seatkey])){
					$out =json_decode($info[$seatkey],true);
					$cur_uid = $out['uid'];
					$userModel =new UserModel($cur_uid);
					$users= $userModel->getInfo();
					$cur_seat_info =array(
							'uid'=>$cur_uid,
							'seatid'=>$i,
							'nickname'=>$users['nickname'],
							'headimgurl'=>$users['headimgurl'],
						);

				}
				$seat_info[]=$cur_seat_info;
			}

			//notify
			$user = $this->mUser->getInfo();
			Socket::sendToChannel("game-{$this->id}", "Elephant", "seat", array(
				'uid' => $uid,
				'seatid' => $pos,
				'state' => self::STATE_NONE,
				'name' => $user['nickname'],
				'owner_info'=>$owner_info,
				'room_info'=>$room_info,
				'seat_info'=>$seat_info,

			));
		}else{
			$this->_error = '没有位置了';
			//没有位置 可以加入房间
			$this->mUser->save(array(
				'roomid' => $this->id,
			));

			return array(
				'roomid' => $this->id,
			);
		}
		//提示座位坐下
		
		return true;
		// return array(
		// 	'roomid' => $this->id,
		// 	'seatid' => $pos,
		// );	
	}
	public function reconnet(){
		//重新绑定房间频道
		Socket::getRouter()->addChannel("game-{$this->id}", SESSIONID);
		$uid = $this->mUser->getUid();
		$user = $this->mUser->getInfo();
		$room = $this->getInfo();
		$game_status =1;
		if($room['state']){
			$game_status=2;
		}
		$owner =isset($room['owner'])?$room['owner']:'';
		$banker =isset($room['banker'])?$room['banker']:'';
		$double =isset($room['banker'])?$room['double']:'';
		$time_way =isset($room['time_way'])?$room['time_way']:'';
		$time_value =isset($room['time_value'])?$room['time_value']:'';
		$create_time =isset($room['time'])?$room['time']:'';
		$game_info =isset($room['game_info'])?$room['game_info']:'';
		if($game_info){
			$game_info_list =json_decode($game_info,true);
			if(is_array($game_info_list)&&$game_info_list){
				foreach ($game_info_list as $cur_seatid => $value) {
						if($cur_seatid==$user['seatid']){
							$type_list =$value['type'];
							$type = key($type_list);
							$combox_new_arr =array(
									'seatid'=>$cur_seatid,
									'type'=>$type,
								);
							if($type==1){
								$combox_new_arr['eat']=2;
								$combox_new_arr['combox_eat_pai']= $type_list[$type]['list_pai'];
								$combox_new_arr['pai']= $type_list[$type]['pai'];
								$combox_new_arr['throw_seatid']= $type_list[$type]['throw_seatid'];
							}
							if($type==2){
								$combox_new_arr['peng']=2;
								$combox_new_arr['combox_peng_pai']= $type_list[$type]['list_pai'];
								$combox_new_arr['pai']= $type_list[$type]['pai'];
								$combox_new_arr['throw_seatid']= $type_list[$type]['throw_seatid'];
							}
							if($type==3){
								$combox_new_arr['gang']=2;
								$combox_new_arr['combox_gang_pai']= $type_list[$type]['list_pai'];
								$combox_new_arr['pai']= $type_list[$type]['pai'];
								$combox_new_arr['throw_seatid']= $type_list[$type]['throw_seatid'];
							}
							if($type==4){
								$combox_new_arr['hu']=2;
								$combox_new_arr['pai']= $type_list[$type]['pai'];
								$combox_new_arr['throw_seatid']= $type_list[$type]['throw_seatid'];
							}
							$game_info_res[] =$combox_new_arr;
							break;
						}
				}
			}

		}

		$system_time =time();
		$left_time = ($create_time + 60*$time_value)-$system_time;
		$left_time =$left_time>0?$left_time:0;
		$room_info[]=array(
				'owner'=>$owner,
				'banker'=>$banker,
	            'double'=>$double,
	            'roomid' => $this->id,
	            'time_way'=>$time_way,
	            'time_key'=>$time_value,
	            'lefttime'=>$left_time,
	            'system_time' => $system_time,
	            'present_quan'=>isset($room['present_quan'])?$room['present_quan']:1,
	            'left_pai'=>count(json_decode($room['desk_majiang'])),
			);
		if($owner){
			$userModel =new UserModel($owner);
			$owner_users= $userModel->getInfo();
			$owner_info[]=array(
					'uid'=>$owner,
		            'seatid'=>$owner_users['seatid'],
		            'nickname'=>$owner_users['nickname'],
		            'headimgurl'=>$owner_users['headimgurl'],
				);
		}
		$myseatid =isset($user['seatid'])?$user['seatid']:'';
		$config_obj=Yaf_Registry::get("config");
		$config_database =$config_obj->database->config->toArray();
		$prefix =$config_database['prefix'];

		$medialTable = new HbModel($prefix.'medias');

		if($myseatid){
			$info = $room;
			for($i=1;$i<=4;$i++){				
				$seatkey ="seat".$i;
				$cur_seat_info=array();
				if(isset($info[$seatkey])){
					$cur_uid = $info[$seatkey]['uid']?$info[$seatkey]['uid']:'';
					$userModel =new UserModel($cur_uid);
					$users= $userModel->getInfo();
					//mdeial_url
					$sql="SELECT * FROM gm_medias WHERE uid=".$cur_uid." AND roomid=".$this->id." ORDER BY created desc";
					$medias = $medialTable->query($sql);
					$voice_url ='';
					if(is_array($medias)&&$medias){
						foreach ($medias as $key => $value) {
							$voice_url =$value['path'];
						}
					}


					$cur_seat_info =array(
							'uid'=>$cur_uid,
							'seatid'=>$i,
							'nickname'=>$users['nickname'],
							'headimgurl'=>$users['headimgurl'],
							'point'=>$point,
							'voice_url'=>$voice_url,
							'throw_front'=>$info[$seatkey]['throw_front'],
						);
					//游戏进行中
					if($myseatid==$i && $game_status==2){
						$cur_seat_info['frontpai']= json_encode($info[$seatkey]['front_rule']);
						$cur_seat_info['handpai']= $this->clearFlower($info[$seatkey][$seatkey]);
						$cur_seat_info['present_flower_nums']=count($info[$seatkey]['get_flower']);
						$cur_seat_info['present_flower']=$info[$seatkey]['get_flower'];

					}
					if($myseatid!=$i && $game_status==2){
						$cur_seat_info['other_handpai'] = count($info[$seatkey][$seatkey]);
						$cur_seat_info['other_frontpai']= isset($info[$seatkey]['frontpai'])?$info[$seatkey]['frontpai']:array();
						$cur_seat_info['other_flowerpai']=$info[$seatkey]['get_flower'];
					}
				}
				$seat_info[]=$cur_seat_info;
			}
		}
		$success = array(
				'game_status'=>$game_status,
				'owner_info'=>$owner_info,
				'room_info'=>$room_info,
				'seat_info'=>$seat_info,
				'game_info'=>$game_info_res,
			);	
		$this->_success=$success;
		return true;
	}
	/**
	 * 清除恢复信息
	 * [clearGameInfo description]
	 * @param  [type] $seatid [description]
	 * @return [type]         [description]
	 */
	public function clearGameInfo($seatid){
		$room = $this->getInfo();
		$game_info =isset($room['game_info'])?$room['game_info']:'';
		$new_game_info=array();
		$game_info =json_decode($game_info,true);
		if($game_info){
			foreach($game_info as  $this_seatid=>$vv){
				if($this_seatid!=$seatid){
					$new_game_info[$this_seatid]=$vv;
				}
			}
		}
		$latest_room['game_info'] = json_encode($new_game_info);
		$this->redis->hMSet(self::INFO_KEY.$this->id,$latest_room);
	}

	/**
	 * 保留状态
	 * [retention description]
	 * @param  [type] $game_info [description]
	 * @return [type]            [description]
	 */
	private function retention($game_info){
		if(!$game_info) return;
		$room['game_info']=json_encode($game_info);
		$this->redis->hMSet(self::INFO_KEY.$this->id,$room);
	}
	//加入房间 只是加入不坐下
	public function join(){
		$uid = $this->mUser->getUid();
		$user = $this->mUser->getInfo();
		$this->mUser->save(array(
				'roomid' => $this->id,
			));
		$this->getInfoEx();
		$roomInfo = $this->redis->hGetAll(self::INFO_KEY . $this->id);
		if(!isset($roomInfo['owner'])||!$roomInfo['owner']){
			$roomlist = $this->redis->hGetAll(self::LIST_KEY);
			$thisroomInfo = json_decode($roomlist[$this->id]);
			$createUser = $thisroomInfo->fromuser;
			$time_way = isset($thisroomInfo->time_way)?$thisroomInfo->time_way:1;
			$time_value = isset($thisroomInfo->setting_value)?$thisroomInfo->setting_value:15;			
			$game_type = isset($thisroomInfo->game_type)?$thisroomInfo->game_type:'dancheng';		
			$double = isset($thisroomInfo->double)?$thisroomInfo->double:1;		
			$redis=RedisDB::factory('user');
			$userlist = $redis->hGetAll(UserModel::USERNAME_KEY);
			if(!$userlist){
				$this->_error = '用户身份错误';
				return false;
			}
			$owner =$userlist[$createUser];
			$roomInfo['owner']=$owner;
			$roomInfo['time_way']=$time_way;
			$roomInfo['time_value']=$time_value;
			$roomInfo['game_type'] =$game_type;
			$roomInfo['double'] =$double;//倍数
			$this->redis->hMSet(self::INFO_KEY . $this->id, $roomInfo);
		}
		//获取房主信息
		if($roomInfo['owner']){
			$owner =intval($roomInfo['owner']);
			$mUser = new UserModel($owner);
			$owner_user = $mUser->getInfo();
			$owner_nickname=$owner_user['nickname'];
			$owner_headimgurl=$owner_user['headimgurl'];
		}
		//对局时长
		// $time_value=$roomInfo['time_value']."分钟";
		// if($roomInfo['time_way']==2){
		// 	$time_value=$roomInfo['time_value'].'圈';
		// }
		$time_way =$roomInfo['time_way'];
		$time_key = $roomInfo['time_value'];
		$dissolve =time()- $roomInfo['created'];
		$double =$roomInfo['double'];
		$banker =isset($roomInfo['banker'])?$roomInfo['banker']:'';
		$create_time = $roomInfo['time'];
		$system_time =time();
		
		$roomInfo = $this->redis->hGet(self::INFO_KEY . $this->id, 'watcher');
		$user['roomid']=$this->id;	
		$data_info =array($uid=>$user);
		$this->redis->hSet(self::INFO_KEY . $this->id, 'watcher', json_encode($data_info));//保存用户加入房间

		$room_info[] =array(
				'owner'=>$owner,
				'banker'=>$banker,
	            'double'=>$double,
	            'roomid' => $this->id,
	            'time_way'=>$time_way,
	            'time_key'=>$time_key,
	            'create_time'=>$create_time,
	            'system_time' => $system_time,
	            'present_quan'=>isset($roomInfo['present_quan'])?$roomInfo['present_quan']:1,
			);
		if($owner){
			$userModel =new UserModel($owner);
			$owner_users= $userModel->getInfo();
			$owner_info[]=array(
					'uid'=>$owner,
		            'seatid'=>$owner_users['seatid'],
		            'nickname'=>$owner_users['nickname'],
		            'headimgurl'=>$owner_users['headimgurl'],
				);
		}


		for($i=1;$i<=4;$i++){
			$info = $this->getInfo();
			$seatkey ="seat".$i;
			$cur_seat_info=array();
			if(isset($info[$seatkey])){
				$cur_uid = $info[$seatkey]['uid'];
				$userModel =new UserModel($cur_uid);
				$users= $userModel->getInfo();
				$cur_seat_info =array(
						'uid'=>$cur_uid,
						'seatid'=>$i,
						'nickname'=>$users['nickname'],
						'headimgurl'=>$users['headimgurl'],
					);

			}
			$seat_info[]=$cur_seat_info;
		}
		Socket::sendToChannel("game-{$this->id}", "Elephant", "join", array(
				'owner_info'=>$owner_info,
				'room_info'=>$room_info,
				'seat_info'=>$seat_info,
			));
		Socket::sendToChannel("game-{$this->id}", "Pushment", "join", array(
				'uid'=>$uid,
				'nickname'=>$user['nickname'],
				'headimgurl'=>$user['headimgurl'],
			));
		$msgModel=new MsgModel($this->id);
		$now_msg = $msgModel->getMsg($user);
		//$msgModel->delete();
		$result =isset($now_msg['data'])?json_decode($now_msg['data'],true):'';
		if(is_array($result) && $result){
			foreach($result as $next){
				$new_msg[]=$next;
			}
		}

		$new_msg[] =array(
				'type'=>'join',
				'is_send'=>1,
				'uid'=>$uid,
				'nickname'=>$user['nickname'],
				'headimgurl'=>$user['headimgurl'],
				'msg'=>'玩家'.$user['nickname'].'进入房间',
			);
		$msgModel->save(array('data'=>json_encode($new_msg)));
		//推送给整个房间
		Socket::sendToChannel("game-{$this->id}", "Pushment", "message", array(
				'type'=>'join',
				'nickname'=>$user['nickname'],
				'headimgurl'=>$user['headimgurl'],
				'msg'=>'玩家'.$user['nickname'].'进入房间',
			));
		Log::DEBUG("owner_info:".json_encode($owner_info)."|room_info:".json_encode($room_info)."|seat_info:".json_encode($seat_info));

		return true;
		
	}
	/**
	 * 获取房间的消息列表
	 * 
	 * @return [type] [description]
	 */
	public function message($user){
		$room = $this->getInfo();
		$msgModel=new MsgModel($this->id);
		$list = $msgModel->getMsg($user);
		return array('msglist'=>json_encode($list));
	}
	public function start(){
		$room = $this->getInfo();
		//清除上把游戏信息
		unset($room['desk_majiang']);
		unset($room['dachu']);
		unset($room['left_pai']);
		for($i=1;$i<=4;$i++){
			$seatkey ="seat".$i;
			$cur_seatinfo =$room[$seatkey];
			$room[$seatkey]=array(
					'uid'=>$cur_seatinfo['uid'],
					'seatid'=>$cur_seatinfo['seatid'],
					'state'=>0,
					'point'=>$cur_seatinfo['point'],
				);
		}
		$this->redis->hMSet(self::INFO_KEY . $this->id,$room);
		// $this->_error=json_encode($room);
		// return false;
		if($this->uid != $room['owner']){
			$this->_error = '没有权限';
			return false;
		}

		if($room['state']){
			$this->_error = '游戏进行中';
			return false;
		}
		$user = $this->mUser->getInfo();
		$myseatid = $user['seatid'];
		$res_majiang = $this->makeMajiang();
		$dachu = array();
		$num = 0;
		$beg_num=0;
		// 如果是新的一局.随机一个庄家 否则就获取当前的庄家id
		$org_time =isset($room['start_time'])&&$room['start_time']?$room['start_time']:0;
		$time_value =isset($room['time_value'])&&$room['time_value']?$room['time_value']:15;//单位分钟
		$banker=isset($room['banker'])&&$room['banker']?$room['banker']:0;
		// $take_turns =isset($room['take_turns'])?$room['take_turns']:'';//玩家坐庄次数
		// if(is_array($take_turns)&&$take_turns){
		// 	sort($take_turns);//排序下
		// 	$small_value=isset($take_turns[0])?$take_turns[0]:0;
		// 	$quan = $small_value/4+1;
		// 	if($small_value%4==0){
		// 		$seat_quan =1;//东风圈
		// 	}elseif($small_value%4==1){
		// 		$seat_quan =2;
		// 	}elseif($small_value%4==2){
		// 		$seat_quan =3;
		// 	}elseif($small_value%4==3){
		// 		$seat_quan =4;
		// 	}
		// }
		$time_way =$room['time_way'];
		if($time_way==2){
			$limit_quan =$room['time_value'];//限定多少圈
			if($quan>$limit_quan){
				$this->_error = '游戏已经到达了圈数';
				return false;
			}
		}
		if(!$banker){
			$seed_banker =array(1,2,3,4);
			$randkey= array_rand($seed_banker);
			$banker =$seed_banker[$randkey];
			//$banker=4;//默认一个玩家
		}
		$cur_time = time();
		$game_info =array();
		for($i = 1; $i <= self::MAX_POS; ++$i){
			// if(!isset($room["seat$i"])){
			// 	continue;
			// }
			$seat = $room["seat$i"];
			// if($i != $user['seatid'] && !$seat['state']){
			// 	$this->_error = '玩家状态错误';
			// 	return false;
			// }

			//$seat =array();
			$length =$i==$banker?14:13;
			$seat_arr=array();
			for($k=0;$k<$length;$k++){
				$seat_arr[]=array_shift($res_majiang);
			}
			$last_result= $this->buhua($seat_arr,$res_majiang);
			$res_majiang = $last_result['cur_majiang'];
			$front =$last_result['flowers'];//花牌
			$seat['isHu']=1;
			if($length==14){//庄家检查是否胡
				$checkResult=$this->checkHu($last_result['cur_seat']);
				$seat['isHu'] = $checkResult?2:1;
				$satisfy_ok=array();
				if($seat['isHu']==2){
					//天胡
					array_push($satisfy_ok, 12);					
				}
				$seat['huInfo']=$satisfy_ok;
			}

			$seat['state'] = self::STATE_PLAYING;
			$cur_seat_arr =$this->sortBy($last_result['cur_seat']);
			$dachu = array_merge($dachu,$cur_seat_arr);

			$response_seat_now = $seat;
			$response_seat_now['pai']=$this->clearFlower($cur_seat_arr);
			$response_seat_now['get_flower'] =is_array($front)&&$front?count($front):0;
			$cur_seat_arr =$this->clearFlower($cur_seat_arr);
			$seat['seat'.$i]= $cur_seat_arr;
			// $seat['front'] = $front;//玩家前面的牌
			$seat['get_flower'] =$front;//我的花牌

			if($i==$myseatid){
				$mylast_seat["seat".$i] = $response_seat_now;
			}else{
				$mylast_seat["seat".$i] =array(
						'isHu'=>$seat['isHu'],
						'state'=>$seat['state'],
						'seatid'=>$i,
						'pai'=>count($cur_seat_arr),
						'get_flower'=>count($front)?count($front):0,
						'present_flower'=>$front,

					);
			}
			$seatTochannel['seat'.$i] =array(
						'current'=>$response_seat_now,
						'uid'=>$seat['uid'],
						'other'=>array(
								'isHu'=>$seat['isHu'],
								'seatid'=>$i,
								'banker'=>$banker,
								'state'=>$seat['state'],
								'pai'=>count($cur_seat_arr),
								'get_flower'=>count($front)?count($front):0,
								'present_flower'=>$front,
							),
				);
			$update["seat".$i] = json_encode($seat);
			
			if($length==14){
				$game_info=array($i=>array('type'=>array('6'=>array())));
			}
			$num++;
		}
		$response_update =json_encode($mylast_seat);
		//保存已经发出的牌
		if($num < 4){
			$this->_error = '玩家人数不足';
			return false;
		}
		$this->retention($game_info);

		$this->lock();
		$update['quan']=$quan?$quan:1;
		$update['present_quan']=$seat_quan?$seat_quan:1;
		$update['pan']=isset($room['pan'])&&$room['pan']?$room['pan']:1;
		$update['banker']=$banker;//随机一个庄家
		$update['current'] = 1;
		$update['state'] = 1;  //状态
		$update['total'] = $num;//当前玩家数量
		$update['left_pai']=count($res_majiang);//剩余牌
		$update['desk_majiang']=json_encode($res_majiang);//当前剩余麻将
		$dachu =$this->sortBy($dachu);
		$update['dachu']=json_encode($dachu);
		$update['start_time'] =$cur_time;//游戏开始时间
		$this->redis->hMSet(self::INFO_KEY . $this->id, $update);
		$this->unlock();
		$this->setTimer();				
		$new_update =array();
		$new_update['game_type']=$room['game_type'];
		$new_update['banker']=$update['banker'];
		$new_update['state']=$update['state'];
		$new_update['left_pai']=$update['left_pai'];
		$new_update['start_time']=$update['start_time'];
		$new_update['pan']=$update['pan'];
		$new_update['present_quan']=$update['present_quan'];
		$new_update['quan']=$update['quan'];
		$roomInfo =json_encode($new_update);

		$now_time = $room['time_value'];//-time()-$update['start_time'];
		$room_info[] =array(
				'owner'=>$room['owner'],
	            'double'=>$room['double'],
	            'banker'=>$banker,
	            'roomid' => $this->id,
	            'time_way'=>$room['time_way'],
	            'time_key'=>$now_time,
	            'create_time'=>$room['time'],
	            'system_time' => time(),
	            'present_quan'=>$new_update['present_quan'],
			);


		$die[] =mt_rand(1,6);
		$die[]= mt_rand(1,6);
		$whole_time=$time_value*60;
		$whole_latest_time = $whole_time-($cur_time-$org_time);
		$lefttime = $org_time?$whole_latest_time:$whole_time;
		for($i=1;$i<=4;++$i){
			$channel_data =array();
			if($i==$myseatid) continue;
			//其它玩家推送
			$number_arr =array(1,2,3,4);
			$b= array();
			foreach($number_arr as $n){
				if($n!=$i){
					$b['seat'.$n] =$seatTochannel['seat'.$n]['other'];
				}else{
					$b['seat'.$n] =$seatTochannel['seat'.$i]['current'];
				}
			}
			$channel_data =json_encode($b);
			$channel_uid =$seatTochannel['seat'.$i]['uid'];
			Socket::sendToUser($channel_uid,"Elephant","start",array(
				'room_info'=>$room_info,
				'seats'=>$channel_data,
				'start'=>2,
				'die'=>$die,
				'lefttime'=>$lefttime,
			));
			Log::DEBUG('开始牌seats:'.json_encode($channel_data));
			//获取房主信息
			if($room['owner']){
				$owner =intval($room['owner']);
				$mUser = new UserModel($owner);
				$owner_user = $mUser->getInfo();
				$owner_nickname=$owner_user['nickname'];
				$owner_headimgurl=$owner_user['headimgurl'];
			}
			Socket::sendToChannel("game-{$this->id}", "Pushment", "owner", array(
				'uid' => $owner,				
				'nickname' => $owner_nickname,
				'headimgurl'=>$owner_headimgurl,
				'present_quan'=>$room['present_quan'],
			));	
			//file_put_contents('cahng.txt',PHP_EOL.$channel_data.PHP_EOL,FILE_APPEND);
		}
		
		$this->_success=array('room_info'=>$room_info,'seats'=>$response_update,'die'=>$die,'start'=>2,'lefttime'=>$lefttime);
		return true;
	}

	/**
	 * 随机生成144张麻将
	 * 1-9 万 11-19 筒子  21-29 条子  31-37东南西北中发白 41-48 春夏秋冬 梅兰竹菊
	 * [makeMajiang description]
	 * @return [type] [description]
	 */
	private function makeMajiang(){
		$majiang=array();
		//万牌
		for($j=0;$j<4;$j++){
			for($i=1;$i<=9;$i++){
				array_push($majiang, $i);
			}
		}
		//筒子牌
		for($j=0;$j<4;$j++){
			for($i=11;$i<=19;$i++){
				array_push($majiang, $i);
			}
		}
		//条子牌
		for($j=0;$j<4;$j++){
			for($i=21;$i<=29;$i++){
				array_push($majiang, $i);
			}
		}
		for($j=0;$j<4;$j++){
			for($i=31;$i<=37;$i++){
				array_push($majiang, $i);
			}
		}
		for ($i=41; $i <=48 ; $i++) { 
			array_push($majiang, $i);
		}
		shuffle($majiang);
		return $majiang;
	}
	public function sortBy($majiang){
		sort($majiang);
		return $majiang;
	}
	private function buhua($seat_arr,$majiang){
		$flowers = array();
		foreach($seat_arr as $next){
			if($next>=41 && $next<=48){
				//$last_arr =array_pop($majiang);
				array_push($flowers, $next);
				while (true) {
					$last_arr =array_pop($majiang);
					if($last_arr<41){
						break;
					}
					array_push($flowers, $last_arr);
				}
				//array_push($seat_arr,$last_arr);
				$seat_arr[]=$last_arr;
			}
		}
		return array('cur_seat'=>$seat_arr,'cur_majiang'=>$majiang,'flowers'=>$flowers);
	}
	public function leave(){
		$redis = RedisDB::factory('user');
		$uid = $this->mUser->getUid();
		$mUser = new UserModel($uid);
		$user = $mUser->getInfo();
		if($user['roomid']){
			$roomInfo = $this->redis->hGet(self::INFO_KEY . $user['roomid'], 'watcher');
			$roomInfo =json_decode($roomInfo);
			$arr=$this->objectToArr($roomInfo);
			unset($arr[$uid]);
			if($arr){
				$this->redis->hSet(self::INFO_KEY . $user['roomid'], 'watcher', json_encode($arr));//保存用户加入房间
			}else{
				$this->redis->hDel(self::INFO_KEY . $user['roomid'], 'watcher');
			}
			//清空座位情况
			$roomInfo = $this->redis->hGetAll(self::INFO_KEY . $user['roomid']);
			if(is_array($roomInfo)&&$roomInfo){
				foreach($roomInfo as $key=>$v){
					if(preg_match('/^seat(.*)/', $key)){
						$this->redis->hDel(self::INFO_KEY . $user['roomid'],$key);
					}
				}
			}

		}
		
		$user['roomid']='';
		$user['seatid']='';
		$res = $redis->hMSet(UserModel::INFO_KEY . $uid, $user);
		return $res;
	}
	private function objectToArr(&$object) {
         $object =  json_decode( json_encode( $object),true);
         return  $object;
	}
	private function clearMyseat($roomInfo,$uid){

		if(is_array($roomInfo)&&$roomInfo){
				foreach($roomInfo as $key=>$v){
					if(preg_match('/^seat(.*)/', $key)){
						$seatInfo =json_decode($v);
						if($seatInfo->uid==$uid){
							$this->redis->hDel(self::INFO_KEY . $this->id,$key);
						}
						
					}
					//从旁观者 变为玩的人
					if($key=='watcher'){
						$roomInfo =json_decode($v);
						$vv=$this->objectToArr($roomInfo);
						unset($vv[$uid]);
						if($vv){
							$this->redis->hSet(self::INFO_KEY . $this->id, 'watcher', json_encode($vv));//保存用户加入房间
						}else{
							$this->redis->hDel(self::INFO_KEY . $this->id, 'watcher');
						}
					}


				}
		}
	}
	public function standup($seatid){
		$room = $this->getInfo();
		$user = $this->mUser->getInfo();
		$seatid =$seatid?$seatid:$user['seatid'];
		$this->redis->hDel(self::INFO_KEY . $this->id, "seat{$seatid}");
		return true;
	}
	public function refresh(){
		$roomInfo = $this->getInfo();
		$state =1;//游戏进行中
		if(!$roomInfo['state']){
			$state =0;//游戏未开始
		}
		$user = $this->mUser->getInfo();
		$seatid= isset($user['seatid'])?intval($user['seatid']):'';
		if($seatid){
			$seatkey = "seat" . $user['seatid'];
		}
		$owner =isset($roomInfo['owner'])?$roomInfo['owner']:'';
		$room_info[] =array(
				'owner'=>$owner,
				'banker'=>isset($roominfo['banker'])?$roominfo['banker']:'',
	            'double'=>$roomInfo['double'],
	            'roomid' => $this->id,
	            'time_way'=>$roomInfo['time_way'],
	            'time_key'=>$roomInfo['time_value'],
	            'create_time'=>$roomInfo['time'],
	            'system_time' => time(),
	            'present_quan'=>$roomInfo['present_quan'],
			);
		if($owner){
			$userModel =new UserModel($owner);
			$owner_users= $userModel->getInfo();
			$owner_info[]=array(
					'uid'=>$owner,
		            'seatid'=>$owner_users['seatid'],
		            'nickname'=>$owner_users['nickname'],
		            'headimgurl'=>$owner_users['headimgurl'],
				);
		}
		for($i=1;$i<=4;$i++){
			$info = $this->getInfo();
			$seatkey ="seat".$i;
			$cur_seat_info=array();
			if(isset($info[$seatkey])){
				$cur_uid = $info[$seatkey]['uid'];
				$userModel =new UserModel($cur_uid);
				$users= $userModel->getInfo();
				$cur_seat_info =array(
						'uid'=>$cur_uid,
						'seatid'=>$i,
						'nickname'=>$users['nickname'],
						'headimgurl'=>$users['headimgurl'],
					);
				//如果是开始游戏了 并且是本人 就加入牌局信息
				
			}
			$seat_info[]=$cur_seat_info;
		}
		if($state==1 ){
			for($i=1;$i<=4;$i++){
				$info = $this->getInfo();
				$seatkey ="seat".$i;
				$cur_seat_info=array();
				if(isset($info[$seatkey])){
					$seatInfo =$info[$seatkey];
					$cur_uid = $seatInfo['uid'];
					$cur_seat_info=array(
							'uid'=>$cur_uid,
							'seatid'=>$i,
							'handpai'=>$i==$seatid?$seatInfo[$seatkey]:'',
							'front'=>$seatInfo['front'],
							'throw_front'=>$seatInfo['throw_front'],
							'flower'=>$seatInfo['get_flower'],
							'handpai_count'=>$i==$seatid?0:count($seatInfo[$seatkey]),
						);
				}
				$pai_info[] =$cur_seat_info;
			}
		}

		$this->_success = array(
				'uid'=>$user['uid'],
				'seatid'=>$seatid,
				'state'=>$state,
				'owner_info'=>$owner_info,
				'room_info'=>$roominfo,
				'seat_info'=>$seat_info,
				'pai_info'=>$pai_info,

			);
		return true;
	}
	public function ready(){
		$room = $this->getInfo();
		// if($this->uid == $room['owner']){
		// 	$this->_error = '房主不用准备';
		// 	return false;
		// }		
		if($room['state']){
			$this->_error = '已经准备了';
			return false;
		}
		$user = $this->mUser->getInfo();
		$seatkey = "seat" . $user['seatid'];
		$seat = $room[$seatkey];
		if($seat['state']>1){
			$this->_error = '游戏开始了';
			return false;
		}
		$this->lock();
		$seat['state'] = self::STATE_READY;
		$this->redis->hSet(self::INFO_KEY . $this->id, $seatkey, json_encode($seat));
		$this->unlock();
		if($user['seatid']){
			$room_info[] =array(
				'owner'=>$room['owner'],
	            'double'=>$room['double'],
	            'roomid' => $this->id,
	            'time_way'=>$room['time_way'],
	            'time_key'=>$room['time_value'],
	            'create_time'=>$room['time'],
	            'system_time' => time(),
	            'present_quan'=>$room['present_quan'],
			);
			if($room['owner']){
				$userModel =new UserModel($room['owner']);
				$owner_users= $userModel->getInfo();
				$owner_info[]=array(
						'uid'=>$room['owner'],
			            'seatid'=>$owner_users['seatid'],
			            'nickname'=>$owner_users['nickname'],
			            'headimgurl'=>$owner_users['headimgurl'],
					);
			}
			$have_ready=0;
			for($i=1;$i<=4;$i++){
				$info = $room;
				$seatkey ="seat".$i;
				$cur_seat_info=array();
				if(isset($info[$seatkey])){
					$cur_uid = $info[$seatkey]['uid'];
					if($info[$seatkey]['state']==1 || $cur_uid==$user['uid']){
						$have_ready++;
					}
					
					$userModel =new UserModel($cur_uid);
					$users= $userModel->getInfo();
					$cur_seat_info =array(
							'uid'=>$cur_uid,
							'seatid'=>$i,
							'nickname'=>$users['nickname'],
							'headimgurl'=>$users['headimgurl'],
						);

				}
				$seat_info[]=$cur_seat_info;
			}
			//提醒房主所有都准备好了
			if($have_ready>=4){			
				if($room['pan']>=2){
					Socket::sendToUser($room['owner'],"Pushment","autorestart");
				}else{
					
					Socket::sendToUser($room['owner'],"Pushment","pushstart",array('start_status'=>2));
				}
				
				
			}			
			Socket::sendToChannel("game-{$this->id}", "Elephant", "ready", array(
				'seatid' => $user['seatid'],
				'action'=>'passive',
				'owner_info'=>$owner_info,
				'room_info'=>$room_info,
				'seat_info'=>$seat_info,
			));
		}		
		return true;
	}
	/**
	 * 操作加锁
	 */
	private function lock()
	{
		$lockName = "oplock-{$this->id}-{$this->uid}";
		if(!DMutex::lock($lockName)){
			throw new Exception('Locked');
		}
	}
	
	/**
	 * 操作解锁
	 */
	private function unlock()
	{
		$lockName = "oplock-{$this->id}-{$this->uid}";
		DMutex::unlock($lockName);
	}
	private function setTimer()
	{
		$this->redis->zadd(self::PLAYING_KEY, time() + self::TIMER_DELAY, $this->id);
	}
	
	private function delTimer()
	{
		$this->redis->zrem(self::PLAYING_KEY, $this->id);
	}
	private function clearFlower($handscards){
		//去除花牌
		foreach($handscards as $key=>$card){
			if($card > 40){
				unset($handscards[$key]);
			}
		}
		$handscards =array_merge(array(),$handscards);
		return $handscards;
	}
	//判断是否胡
	public function checkHu($handscards){
		if(!is_array($handscards)|| !$handscards){
			$this->_error='数据类型错误.';
			return false;
		}
		//是否已经存在8张花  有就直接胡牌了
		$mycatchFlowers =0;
		foreach($handscards as $key=>$card){
			if($card>40&&$card<49){
				$mycatchFlowers++;
			}
		}
		if($mycatchFlowers>=8){
			return true;
		}

		//去除花牌
		$handscards=$this->clearFlower($handscards);
		sort($handscards);
		//特殊牌处理
		$isHu=false;
		$handsCount=count($handscards);
		$hu_array=array(2,5,8,11,14,18);
		//手牌数量不是3n+2 或者18
		if(!in_array($handsCount,$hu_array)){
			$this->_error=$isHu;
			return false;
		}

		if($handsCount==18){//杠胡
			$isHu=$this->isGangHu($handscards);
		}	
		if($handsCount==14){
			$isHu =$this->isShisanyao($handscards);
			if(!$isHu){
				//对对胡
				$isHu=$this->isDuiduihu($handscards);
			}
		}
		if(!$isHu){
			$isHu = $this->basicHu($handscards);
		}
		//$this->_error=$isHu;
		return $isHu;
	}
	private function filterShunzi(& $handscards){
		$total =count($handscards);
		for($i=0;$i<$total;$i++){
			for($j=$i+1;$j<$total-1;$j++){
				if($handscards[$j-1]+1==$handscards[$j] && $handscards[$j]+1==$handscards[$j+1]){
					if($j>1 && $handscards[$j-1]==$handscards[$j-2]) continue;
					unset($handscards[$j-1]);
					unset($handscards[$j]);
					unset($handscards[$j+1]);
					$handscards =array_merge(array(),$handscards);
					$this->filterShunzi($handscards);
					break 2;
				}
			}
		}
		
		return $handscards;
	}
	public function filternewShunzi(& $handscards){
		$total =count($handscards);
		for($i=0;$i<$total;$i++){
			for($j=$i+1;$j<$total-1;$j++){
				if($handscards[$j-1]<31 && $handscards[$j]<31 && $handscards[$j+1]<31){
					if($handscards[$j-1]+1==$handscards[$j] && $handscards[$j]+1==$handscards[$j+1]){
						if($j>1 && $handscards[$j-1]==$handscards[$j-2]) continue;
						unset($handscards[$j-1]);
						unset($handscards[$j]);
						unset($handscards[$j+1]);
						$handscards =array_merge(array(),$handscards);
						$this->filternewShunzi($handscards);
						break 2;
					}
				}
			}
		}
		
		return $handscards;
	}
	private function filterddShunzi($handscards){
		foreach($handscards as $key=>$v){
			if($key>0){
				$pai_0 = $v-1;
				if($pai_0==$pai_1) continue;
			}
			$pai_1=$v;
			$pai_2=$v+1;
			$pai_3=$v+2;
			
			$co =array($pai_1,$pai_2,$pai_3);
			if(in_array($pai_1,$handscards) && in_array($pai_2, $handscards) && in_array($pai_3, $handscards)){
				foreach($handscards as $key=>$v){
					if(!$co) break;					
					if(in_array($v, $co)){
						unset($handscards[$key]);
						$new_co=array();
						foreach($co as $coo){
							if($coo!=$v){
								$new_co[]=$coo;
							}
						}
						$co =$new_co;
					}
				}
			}
		}
		$handscards =array_merge(array(),$handscards);
		return $handscards;
	}
	/**
	 * 普通胡
	 * [basicHu description]
	 * @param  [type] $handscards [description]
	 * @return [type]             [description]
	 */
	private function basicHu($handscards){
		$arr_nums = array();
		//过滤掉顺子
		$handscards=$this->filternewShunzi($handscards);
		$handscards =$this->filterddShunzi($handscards);
		$total =count($handscards);
		for ($i=0; $i < $total; $i++) { 
			for ($j=$i+1; $j <$total; $j++) { 
				if($handscards[$i]==$handscards[$j]){
					if(isset($arr_nums[$i])){
						$arr_nums[$i]+=1;
					}else{
						if(!isset($arr_nums[$i-1]) ){
							$arr_nums[$i]=2;
						}
						
					}
				}
			}
		}
		$isHu=false;
		$this_cards = $handscards;
		if(is_array($arr_nums)&&$arr_nums){
			foreach ($arr_nums as $key => $value) {
				if($value!=2) continue;
				$this_cards = $handscards;
				array_splice($this_cards,$key,2);
				$isHu=$this->threecombox($this_cards);
				if($isHu){
					break;
				}
			}
		}
		if(!$isHu){
			$duidui=array();
			if(is_array($arr_nums)&&$arr_nums){
				foreach ($arr_nums as $key => $value) {
					if($value==2){
						array_push($duidui,$handscards[$key]);
					}
				}
			}
			if(in_array(count($duidui),array(4,7))){
				for($i=0;$i<count($duidui);$i++){
					for($j=$i+1;$j<count($duidui)-1;$j++){
						if($duidui[$i]==$duidui[$j]-1 && $duidui[$j]==$duidui[$j+1]-1){
							foreach($handscards as $thkey=>$next){
								if(in_array($next,$duidui)){
									unset($handscards[$thkey]);
								}
							}
						}
					}
				}
			}
			if(!$handscards) $isHu=true;
		}
		return $isHu;
	}
	/**
	 * 刻字或者顺子
	 * [threecombox description]
	 * @return [type] [description]
	 */
	private function threecombox($this_cards){		
		$numbers =count($this_cards);
		if($numbers%3!=0) return false;
 		$isHu=true;
 		//print_r($this_cards);
		if($numbers>2){
			for ($i=0; $i <$numbers-2; $i++) { 
				//刻字
				if($this_cards[$i]==$this_cards[$i+1]&& $this_cards[$i] ==$this_cards[$i+2]){
					array_splice($this_cards,$i,3);		
					return	$this->threecombox($this_cards);
				}elseif($this_cards[$i]==$this_cards[$i+1] && $this_cards[$i+1]+1==$this_cards[$i+2]){					
					// array_shift($this_cards);
					// array_shift($this_cards);
					// array_shift($this_cards);
					//return $this->threecombox($this_cards);
				}

			}
		}
	    if(is_array($this_cards) && $this_cards) $isHu=false;
		return $isHu;
	}
	private function isDuiduihu($handscards){
		$isHu=true;
		$cur_arrm =  $handscards;
		while (count($cur_arrm) && $isHu) {
			if($cur_arrm[0]==$cur_arrm[1]){
				array_shift($cur_arrm);
				array_shift($cur_arrm);
			}else{
				$isHu=false;
				break;
			}
		}
		return $isHu;
	}
	private function isGangHu($handscards_input){
		$isHu=false;
		$this->gangArr($handscards_input,$aResult);
		$handscards=$aResult;
		if(count($aResult)==2){
			$handsCount = count($handscards);
			for ($i=0; $i <$handsCount-1 ; ++$i) { 
					if($handscards[$i]==$handscards[$i+1]){
						$isHu=true;
						break;
					}
			}
		}
		//去除杠 ，剩下一对 不是2个不是胡

		return $isHu;
	}
	private function gangArr($gangArr,& $aResult){
		for ($i=0; $i <count($gangArr)-3; $i++) { 
			if($gangArr[$i]==$gangArr[$i+1] && $gangArr[$i]==$gangArr[$i+2]&& $gangArr[$i]==$gangArr[$i+3]){
				array_splice($gangArr,$i,4);
				$aResult =$gangArr;
				$this->gangArr($gangArr,$aResult);
				break;
			}
		}
	}
	private function isShisanyao($handCards){
		for($j=0;$j< count($handCards)-1;++$j){
			if($handCards[$j]==$handCards[$j+1]){
				unset($handCards[$j+1]);
				break;
			}
		}
		$handCards =array_merge(array(),$handCards);
		$shiSanYaoArr = array(1,9,11,19,21,29,31,32,33,34,35,36,37);
		if($handCards==$shiSanYaoArr){
			return true;
		}else{
			return false;
		}
	}
	private function allGang($info){
		$total=0;
		for($i=1;$i<=4;$i++){
			$seatkey ="seat".$i;
			$cur_userInfo = $info[$seatkey];
			$mypai= $this->objectToArr($cur_userInfo);
			$cur_seat_gang=0;
			if(isset($mypai['gang'])){
				foreach($mypai['gang'] as $numbers){
					$cur_seat_gang+=intval($numbers);
				}
			}
			$total+=$cur_seat_gang;
		}
		return $total;
	}
	/**
	 * 切换庄家 轮循是否到下一个圈 
	 * [changeZhuang description]
	 * @param  [type] $mymopai [description]
	 * @return [type]          [description]
	 * seatid  最小胡的人座位id
	 */
	public function changeZhuang($mymopai,$isHu=1,$seatid=0){
		$banker = $this->redis->hGet(self::INFO_KEY.$this->id,'banker');
		$dachu = $this->redis->hGetAll(self::INFO_KEY.$this->id);		
		$user = $this->mUser->getInfo();
		$seatid = $seatid >0 ? $seatid:$user['seatid'];//胡牌人的座位id

		$banker =intval($banker);//座位id
		$room = $this->getInfo();
		if($isHu==2){
			$org_banker = $dachu['banker'];//原来的庄家
			$org_present_quan =$dachu['present_quan'];//原来的圈
			$uid = $this->mUser->getUid();
			$user = $this->mUser->getInfo();

			//计算庄家和圈	
			if($org_banker!=$seatid){
				$dachu['banker'] = $org_banker==4?1:++$org_banker;
				//计算圈
				if($org_banker==4 ){
					++$org_present_quan;
					$org_present_quan=$org_present_quan>4?1:$org_present_quan;
					
					$dachu['present_quan']=$org_present_quan;
				}	
				
				$this->redis->hMSet(self::INFO_KEY . $this->id,$dachu);
			}

		}else{
			//流局
			$seatkey ="seat".$banker;
			$seatInfo =isset($room[$seatkey])?$room[$seatkey]:'';
			if($seatInfo){
				$mypai= $this->objectToArr($seatInfo);
				$mygang = isset($mypai['gang'])?$mypai['gang']:0;//明杠
				$mypai =$mypai["$seatkey"];
				$allpai =array_merge($mypai,$mymopai);
				$blackgang=$this->findPai($allpai,null);//暗杠
				if($mygang || $blackgang){
					$next_banker = $this->findNextBanker($banker);
					$dachu['banker']=$next_banker;
					$dachu['take_turns'] =$take_turns?$take_turns[$next_banker]+1:0;
					$this->redis->hMSet(self::INFO_KEY . $this->id,$dachu);
				}
				// $seed_banker =array(1,2,3,4);
				// $randkey= array_rand($seed_banker);
				// $banker =$seed_banker[$randkey];
				// $dachu['banker']=$banker;
				// $this->redis->hMSet(self::INFO_KEY . $this->id,$dachu);
			}
		}	
	}
	private function findNextBanker($banker){
		$basic_arr =array(1,2,3,4);
		if(!in_array($banker,$basic_arr)){
			return false;
		}
		if($banker==4){
			$next_banker=1;
		}else{
			$next_banker=$banker++;
		}
		return $next_banker;

	}
	public function touchcard(){
		$uid = $this->mUser->getUid();
		$info = $this->getInfo();
		$room=$info;
		$user = $this->mUser->getInfo();
		$seatkey='seat'.$user['seatid'];
		$cur_userInfo =$info[$seatkey];
		$mypai= $this->objectToArr($cur_userInfo);
		$player_has_flowers=$mypai['get_flower'];
		$player_action =$mypai['player_action'];
		$myfront =$mypai['front'];
		$myfront =$this->changeFrontPai($myfront);
		$seat_offer =$mypai;		
		$mypai =$mypai["$seatkey"];
		$isExists_gang =isset($player_action['gang'])?2:1;
		$deskcards =$info['desk_majiang'];
		$db_dachu = json_decode($info['dachu']);
		$deskcards_arr =json_decode($deskcards);
		$mymopai=array();
		//获取当前已经出牌的牌
		$dachu = $this->redis->hGet(self::INFO_KEY.$this->id,'dachu');
		$dachu =json_decode($dachu);
		$flowers =$this->getFlowers($dachu);
		$allgang=$this->getallgang($info);
		$gang_total=$allgang*2;//当前所有杠的数量
		$over=false;
		while (true) {
			$left_numbers = count($deskcards_arr);//当前牌的数量
			$basic_number = $flowers<8?14+$gang_total:16+$gang_total;
			if($left_numbers<=$basic_number){
				$over = true;
				break;
			}

			if(!$mymopai && $isExists_gang==1){
				$mopai= array_shift($deskcards_arr);//获取第一个牌

				$this->redis->hMSet(self::INFO_KEY . $this->id, array('desk_majiang'=>json_encode($deskcards_arr)));
			}else{
				$mopai=array_pop($deskcards_arr);
				$this->redis->hMSet(self::INFO_KEY . $this->id, array('desk_majiang'=>json_encode($deskcards_arr)));
			}
			array_push($mymopai, $mopai);
			if($mopai <40){
				break;
			}
		}
		//$over =true;
		if($over){
			//庄家是否有杠 有杠下家坐庄
			$this->changeZhuang($mymopai);
			//$this->_error=array('gameover'=>2,'tips'=>'流局');
			$scorelist =array();
				for($i=1;$i<=4;$i++){
					$seatkey ='seat'.$i;
					$seatinfo = $room[$seatkey];
					$uid =$seatinfo['uid'];
					$mUser = new UserModel($uid);
					$info=$mUser->getUserInfoByUid();
					$nickname =isset($info['nickname'])?$info['nickname']:'';
					$headimgurl =isset($info['headimgurl'])?$info['headimgurl']:'';

					$scorelist[$i]=array(
							'nickname'=>$nickname,
							'headimgurl'=>$headimgurl,
							'score'=>0,
							'pai'=>'',
							'basic_score'=>0,
						);
				}

			$pai_list[] =array(
							'front_pai'=>array(),
							'handpai'=>array(),
							'pai_type'=>array('title'=>'','score'=>0),
							'all_taishu'=>0,
							'pai'=>'',
						);
			$list['pai_list'] = $pai_list;
			$list['scorelist'] = $scorelist;
			$list['giveup'] = 2;
			Socket::sendToChannel("game-{$this->id}", "Pushment", "over", $list);
			//清理
			$dachu = $this->redis->hGetAll(self::INFO_KEY.$this->id);
			for($i=1;$i<=4;$i++){
				$seatkey ="seat".$i;
				$cur_seatinfo =$dachu[$seatkey];
				$myseatInfo =json_decode($cur_seatinfo,true);
				$seatinfo =array(
						'uid'=>$myseatInfo['uid'],
						'seatid'=>$myseatInfo['seatid'],
						'state'=>0,
						'point'=>$myseatInfo['point'],
					);
				$dachu[$seatkey]=json_encode($seatinfo);
			}
			$dachu['desk_majiang']='';
			$dachu['dachu']='';
			$dachu['left_pai']='';
			$dachu['guo_order']='';
			$dachu['throw_order']='';
			$dachu['check_order']='';
			$dachu['game_info']='';
			$dachu['state']=0;
			$dachu['hu_order']='';
			$dachu['pan']=$dachu['pan']+1;
			$this->redis->hMSet(self::INFO_KEY . $this->id,$dachu);
			$this->_success="流局";
			return true;
		}
		$combo_arr_all = array_merge($mypai,$mymopai);
		Log::DEBUG($user['seatid'].'正常组合摸牌'.json_encode($mymopai).'检测胡牌的'.json_encode($combo_arr_all));
		$prevpai =$mypai;//原来的手牌
		$isHu = $this->checkHu($combo_arr_all);
		$isHu =$isHu?2:1;
		//判断是否有台数

		if($isHu==2){
			$satisfy_ok=array();
			$dachu = $room['dachu'];
			$deskcards_arr =$room['desk_majiang'];
			$dachu =json_decode($dachu);
			$flowers =$this->getFlowers($dachu);
			$allgang=$this->getallgang($room);
			$gang_total=$allgang*2;//当前所有杠的数量
			$isExists_gang =isset($player_action['gang'])?2:1;
			$basic_number = $flowers<8?14+$gang_total:16+$gang_total;
			if($isExists_gang==2){//本人有杠
				//杠开
				$gang_somebody=$player_action['gang'];
				if($gang_somebody==$user['seatid']){
					array_push($satisfy_ok, 9);
				}else{
					array_push($satisfy_ok, 10);// 送杠胡
				}
				
			}
			array_push($satisfy_ok, 6);
			//如果手牌只有一张的时候就是大吊
			if($prevpai==1){
				array_push($satisfy_ok, 7);
			}
			//海底捞月
			$left_numbers = count($deskcards_arr);//当前牌的数量
			if($left_numbers==$basic_number){
				array_push($satisfy_ok, 17);
			}
			$aResult = $this->sumscore($user['seatid'],array($mymopai),$user['seatid'],$satisfy_ok);
			if(!$aResult['all_taishu']){
				$isHu=1;
			}
		}
		if($isHu==1){
			//不胡的情况加到手牌 胡牌不加手牌 
			$combo_arr_all =array_merge($mypai,$mymopai);
		}else{
			//胡牌不加入手牌
			$combo_arr_all =$mypai;
		}
		//获取花的组合
		$present_flower=array();
		foreach($mymopai as $next){
			if($next>=41 && $next<=48){
				array_push($present_flower, intval($next));
			}
		}
		$all_flowers = array_merge($player_has_flowers,$present_flower);
		$seat_offer['get_flower']=$all_flowers;
		//$seat_offer['isHu']=$isHu;
		//file_put_contents('myhandspai.txt','mopai|'.$seatkey.'|'.json_encode($combo_arr).PHP_EOL,FILE_APPEND);
		$seat_offer["$seatkey"]=$this->sortBy($combo_arr_all);

		

		$upsert['dachu'] = json_encode(array_merge($db_dachu,$mymopai));
		$is_gang=false;
		$pai =$this->clearFlower($mymopai);//过滤花
		if($isHu==1){
			$is_gang= $this->findPai($prevpai,$pai);
		}
		$gang =$is_gang?2:1;
		if($gang==1){
			//判断台面是否可以杠
			$gang = $this->findPai($myfront,$pai);
		}


		$throw_seatid =$user['seatid'];
		$seat_offer['player_action'] = array();
		$upsert["$seatkey"]=  json_encode($seat_offer);
		$this->redis->hMSet(self::INFO_KEY . $this->id, $upsert);
		$combox_game_info =array();
		if($isHu==2){
			$combox_game_info = array(4=>array('pai'=>$pai,'throw_seatid'=>$throw_seatid));
		}
		if($gang==2){
			$gang_arr =array($pai,$pai,$pai);
			$combox_gang_pai_all=implode(',', $gang_arr);
			$combox_game_info = array(3=>array('pai'=>is_array($pai)?current($pai):$pai,'list_pai'=>array($combox_gang_pai_all),'throw_seatid'=>$throw_seatid));
		}
		if(empty($combox_game_info)){
			//直接出牌了
			$combox_game_info = array( 6=>array());
		}
		$game_info = array(
				$throw_seatid=> array(
						'type'=>$combox_game_info,
					),
			);
		$this->retention($game_info);
		$left_pai =count($deskcards_arr);
			$list =array(
				'event'=>'passive',
				'throw_seatid'=>$throw_seatid,
				'left_pai'=>$left_pai,
				'present_flower_nums'=>count($present_flower),
				'pai_nums'=>count($pai),//摸的牌
				'present_flower'=>$present_flower,
				'hu'=>1,
				'gang'=>1,
			);
			Socket::sendToChannel("game-{$this->id}", "Elephant", "touchcard", $list);
		
		if($gang==2) {
			$pai_arr =array($pai,$pai,$pai,$pai);
			//查询手牌其它可以杠的牌
			$combox_gang_pai[] = implode(',', $pai_arr);
			$gang_pai=array();
			foreach($mypai as $next){
					$is_ok = $this->findPai($mypai,$next);
					if($is_ok){
						$gang_pai[]=$next;
					}
			}
			$count =count($gang_pai);
			for($i=0;$i<$count;$i++){
				if($i%4==0){
					$this_gang_arr = array($gang_pai[$i],$gang_pai[$i],$gang_pai[$i],$gang_pai[$i]);
					$combox_gang_pai[]= implode(',',$this_gang_arr);
				}
			}
			//台面牌杠牌
			$myfront =$this->sortBy($myfront);
			$now_gang = $this->selfTouch($myfront,$prevpai);
			if(is_array($now_gang)&&$now_gang){
				foreach($now_gang as $nv){
					$combox_gang_pai[]=$nv;
				}
			}
		}
		Log::DEBUG('正常摸牌'.json_encode($pai));
		$this->_success= array('event'=>'active','present_flower_nums'=>count($present_flower),'pai'=>$pai,'left_pai'=>$left_pai,'present_flower'=>$present_flower,'hu'=>$isHu,'gang'=>$gang,'throw_seatid'=>$throw_seatid,'combox_gang_pai'=>$combox_gang_pai);
		return true;
	}
	private function getFlowers($dachu){
		$flowers=0;
		if(is_array($dachu)&&$dachu){
			foreach ($dachu as  $value) {
				if($value>40){
					$flowers++;
				}
			}
		}
		return $flowers;
	}
	public function getFindEat(){
		$seatid =2;
		$throw_seatid=2;
		$pai =array(9);
		$handpai =array(6,6,9,9,17,18,19,23,23,23,27,28,29);
		$frontpai=array();
		$user = $this->mUser->getInfo();
		$info = $this->getInfo();
		//切换庄家和牌局重置
		//$double =$info['double'];//倍数 1
		$banker =$info['banker'];//当前庄家
		if($banker!=$user['seatid']){
			$dachu['banker']= $user['seatid'];
			$this->redis->hMSet(self::INFO_KEY . $this->id,$dachu);
		}
		$seatkey ="seat".$seatid;
		$myseatInfo =$info[$seatkey];//我的牌信息	
		$present_quan =$info['present_quan'];//目前圈
		//$handpai =$myseatInfo[$seatkey];
		
		$throw_front=isset($myseatInfo['throw_front'])?$myseatInfo['throw_front']:'';//我仍出的牌

		$throwkey="seat".$throw_seatid;
		$throwInfo =$info[$throwkey];
		$banker_throw_front=isset($throwInfo['throw_front'])?$throwInfo['throw_front']:'';//打出的牌
		$player_action =isset($throwInfo['player_action'])?$throwInfo['player_action']:'';
		$gangInfo="";
		if($player_action){
			$gangInfo=isset($player_action['gang'])?$player_action['gang']:'';
		}
		$allpai =$pai?array_merge($handpai,array($pai)):$handpai;//所有牌包括抓取的

		$allpai=$this->clearFlower($allpai);
		$handpai =$this->clearFlower($handpai);
		$handpai =$this->sortBy($handpai);

		
		$flowerpai = isset($myseatInfo['get_flower'])?$myseatInfo['get_flower']:'';
		$flowerpai =array(42);
		//$frontpai =isset($myseatInfo['front'])?$myseatInfo['front']:'';//吃 碰 杠
		
		//$frontpai =is_array($frontpai)?$frontpai:array();
		

		$frontpai =$this->sortBy($frontpai);
		if(!$handpai||!$frontpai||!$pai) return false;
		$eat =isset($myseatInfo['eat'])?$myseatInfo['eat']:'';
		if(is_array($eat)&&$eat){
			foreach ($eat as $value) {
				$eat_total+=$value;
			}
		}
		$peng =isset($myseatInfo['peng'])?$myseatInfo['peng']:'';
		if(is_array($peng)&&$peng){
			foreach ($peng as $value) {
				$peng_total+=$value;
			}
		}
		$gang =isset($myseatInfo['gang'])?$myseatInfo['gang']:'';
		if(is_array($gang)&&$gang){
			foreach ($gang as $value) {
				$gang_total+=$value;
			}
		}
		//$peng="";
		//print_r($allpai);exit;
		//牌型ABC ABC ABC ABC AA 。没有碰过,AA不能是有台数风牌 1台
		//$satisfy_ok = array();
		//8花胡
		//$satisfy_ok =array();
		if(count($flowerpai)==8){
			array_push($satisfy_ok,18);
		}
		//4花
		if(count($flowerpai)==4){
			$oba =array(41,42,43,44);
			$obb =array(45,46,47,48);
			$before=true;
			$after= true;
			foreach($flowerpai as $aflowerpai){
				if(!in_array($aflowerpai,$oba)){
					$before= false;
				}
				if(!in_array($aflowerpai,$obb)){
					$after= false;
				}
			}
			if($before||$after){
				array_push($satisfy_ok, 19);
			}
		}

		$myhandpai_counts=count($allpai);
		if($myhandpai_counts==14){
			//十三幺
			if($this->isShisanyao($allpai)){
				array_push($satisfy_ok,27);
			}
		}
		//平胡
		if($this->isPinghu($allpai) && !$peng){
			array_push($satisfy_ok, 1);
		}
		//边胡
		$pai=$this->clearFlower($pai);
		$pai =isset($pai[0])?$pai[0]:$pai;
		$this->findBianHu($pai,$handpai,$frontpai,$satisfy_ok);
		$this->findDuidao($pai,$handpai,$satisfy_ok);
		//手上只有一张牌的时候
		if(count($frontpai)==1 && is_array($frontpai)){
			array_push($satisfy_ok, 7);
		}
		//对对胡
		$this->findDuiDuiHu($pai,$handpai,$frontpai,$satisfy_ok);
		$this_seatid =$user['seatid'];
		if($gangInfo && $user['seatid']!=$gangInfo){
			array_push($satisfy_ok, 11);//拉杠
		}
		//门清
		if(empty($frontpai)){
			array_push($satisfy_ok, 25);
		}
		if(is_array($banker_throw_front) && count($banker_throw_front)==1 && !$throw_front){
			//地胡
			array_push($satisfy_ok, 13);
		}
		$tag=$this->qingyise($pai,$handpai,$frontpai);
		if($tag==2){
			array_push($satisfy_ok, 14);
		}
		$this->hunyise($pai,$handpai,$frontpai,$satisfy_ok);
		$this->ziyise($pai,$handpai,$frontpai,$satisfy_ok);
		$this->dasanyuan($pai,$handpai,$frontpai,$satisfy_ok);
		$taishu =$this->zhongfabai($pai,$handpai,$frontpai);
		$this->zhengfeng($pai,$handpai,$frontpai,$seatid,$satisfy_ok);
		$this->quanfeng($pai,$handpai,$frontpai,$present_quan,$satisfy_ok);
		$zheng_yehua = $this->zhenghuayehua($flowerpai,$seatid,$satisfy_ok);
		//西周麻将
		if($info['game_type']=='xizhou'){
			$this->bangao($pai,$handpai,$frontpai,$satisfy_ok);
			$this->tuobangao($pai,$handpai,$satisfy_ok);
			// 板高     牌型ABC+ABC或AABBCC      6台
			// 双板高     牌型ABC+ABC+DEF+DEF或AABBCC+DDEEFF     15台
			// 托板高     牌型ABC+ABC+ABC或AAABBBCCC（不能为碰出的）     25台
			// 断幺     牌型内无1、9、风牌、中发白     1台
		}
		$type =$info['game_type']=="xizhou"?2:1;	
		if(is_array($satisfy_ok)&&$satisfy_ok){
			$str=implode(",", $satisfy_ok);
		}
		$config_obj=Yaf_Registry::get("config");
		$config_database =$config_obj->database->config->toArray();
		$prefix =$config_database['prefix'];

		$rulesTable = new HbModel($prefix.'majiang_rules');			
		$options['where']=array('type'=>$type ,'pos'=>array('IN', $str));
		$dblist = $rulesTable->select($options);
		$aList =array(); 
		$all_taishu=0;
		//zhenghua
		if($zheng_yehua['zhenghua']){
			$condition['where']= array('type'=>$type ,'pos'=>24);
			$hualist = $rulesTable->select($condition);
			if(is_array($hualist)&&$hualist){
				foreach($hualist as $v){
					$db_zhenghua=$v['score'];
					$aList[]=array('title'=>$v['title'],'score'=>$v['score']);
				}
			}
			$all_taishu = $zheng_yehua['zhenghua']*$db_zhenghua;
		}
		//yehua
		if($zheng_yehua['yehua']){
			$condition['where']= array('type'=>$type ,'pos'=>26);
			$hualist = $rulesTable->select($condition);
			if(is_array($hualist)&&$hualist){
				foreach($hualist as $v){
					$db_yehua=$v['score'];
					$aList[]=array('title'=>$v['title'],'score'=>$v['score']);
				}
			}
			$all_taishu += $zheng_yehua['yehua']*$db_yehua;
		}
		if(is_array($dblist)&&$dblist){
			foreach($dblist as $v){
				$all_taishu+=$v['score'];
				$aList[]=array('title'=>$v['title'],'score'=>$v['score']);
			}
		}
		if($taishu){
			array_push($aList,array('title'=>'中发白','score'=>$taishu));	
		}
		$all_taishu+=$taishu;
		
		 $ss=array(
				'all_taishu'=>$all_taishu,
				'aList'=>$aList,
			);
		print_r($ss);
	}
	private  function selfTouch($frontpai,$handpai){
		$frontpai= $this->filterShunzi($frontpai,'');
		$frontpai =$this->filterduiduiShunzi($frontpai,'');
		$static_list = $this->commonDouble($frontpai);
		$three_pai=array();
		$mypai =array();
		if(is_array($static_list)&& $static_list){
		 	foreach($static_list as $keys=>$next){
		 		if($next==3){
	 				array_push($three_pai, $mypai[$keys]);
		 		}
			}
		}
		$forgang=array();
		foreach($handpai as $next){
			if(in_array($next,$three_pai)){
				array_push($forgang,$next);
			}
		}
		$combox_gang_pai =array();
		if(is_array($forgang)&&$forgang){
			foreach ($forgang as  $cangang) {
				$nextgang =array($cangang,$cangang,$cangang,$cangang);
				$combox_gang_pai[]=implode(',', $nextgang);		
			}
		}
		return $combox_gang_pai;

	}
	public function clearFrontAndFrontRule($front,$front_rule,$throw_seatid,$pai){
		$new_front=array();
		if(is_array($front)&&$front){
			foreach ($front as  $value) {
				$eat_peng_gang_arr = explode(',', $value);
				if(!in_array($pai,$eat_peng_gang_arr)){
					$new_front[]=$value;
				}
			}
		}
		$new_front_rule =array();
		if(is_array($new_front_rule)&&$new_front_rule){
			foreach ($new_front_rule as  $value) {
				$eat_peng_gang_arr = explode(',', $value['peng']);
				if($pai==$value['pai'] && in_array($pai,$value['peng']) ){
					continue;
				}
				$new_front_rule[]=$value;
			}
		}


		$new_gang_pai=array($pai,$pai,$pai,$pai);
		$new_front_rule[] = array(
										'gang'=> implode(',', $new_gang_pai),
										'pai'=>$pai,
										'throw_seatid'=>$throw_seatid,
									);

		$all =array('front'=>$new_front,'front_rule'=>$new_front_rule);
		return $all;
	}
	/**
	 * 处理打出的牌
	 * [shots description]
	 * @param  [type] $pai [description]
	 * @return [type]      [description]
	 */
	public function shots($pai,$throwType){
		$uid = $this->mUser->getUid();
		$user = $this->mUser->getInfo();
		$seatid =$user['seatid'];
		$seatkey='seat'.$user['seatid'];
		$room = $this->getInfo();
		$throwType =intval($throwType);
		//吃 碰 杠  胡
		//下家可以吃
		$myhandspai = $room[$seatkey];
		$myhandspai = $myhandspai[$seatkey];
		$myfront = isset($room['front'])&&$room['front']?$room['front']:'';
		$myfront_rule = isset($room['front'])&&$room['front']?$room['front']:'';
		Log::DEBUG($seatid.'仍了一张牌seats:'.json_encode($myhandspai).'|打出的牌'.$pai);

		if(!in_array($pai,$myhandspai)){
			$this->_error='没有这张牌可以打';
			return false;
		}
		if($throwType==1){//自己杠
			//杠
			$throw_seatid =$seatid;
			$next_pai =$myhandspai;//我的牌
				if($next_pai){
					$counts=0;
					$gangOne=$pai;
					foreach($next_pai as $thiskey=>$next){
					
						if($next==$gangOne){
							$counts++;
						}
					}
				}
				$is_front=1;
				if(!$counts){
					//clear 
					$is_front=2;
					$aFrontRestlt = $this->clearFrontAndFrontRule($myfront,$myfront_rule,$throw_seatid,$pai);


				}else{
					if($counts!=3){
						$this->_error='杠牌牌型错误.';
						return false;
					}
					foreach($next_pai as $key=>$next){
						if($next==$gangOne){
							unset($next_pai[$key]);
						}
					}
				}
				if($is_front==1){
					$new_gang_pai=array($gangOne,$gangOne,$gangOne,$gangOne);
					$seat_list = $this->redis->hGet(self::INFO_KEY.$this->id,$seatkey);
					$seat_list =json_decode($seat_list);
					//如果有原来的牌就先去了
					$front_list =$seat_list->front;
					//去除原来的
					$new_front_list = array();
					if(is_array($front_list)&& $front_list){
						foreach ($front_list as $key => $value) {
							$out_front_api=  explode(',', $value);
							if(in_array($gangOne,$out_front_api)){
								continue;
							}
							$new_front_list[]=$value;
						}
					}

					//$front_list = $now_front?array_merge($now_front,$new_peng_pai):$new_gang_pai;
					$present_gang =$seat_list->gang?$seat_list->gang->$throw_seatid:0;

					$new_front_list[]= implode(',', $new_gang_pai);

					$seat_list->front=$new_front_list;
					$myfront_rule[] = array(
										'peng'=> implode(',', $new_gang_pai),
										'pai'=>$pai,
										'throw_seatid'=>$throw_seatid,
									);

					$seat_list->front_rule=$myfront_rule;
				}else{
					$seat_list->front =$aFrontRestlt['front'];
					$seat_list->front_rule=$aFrontRestlt['front_rule'];
				}
				// $now_throw_front = $seat_list->throw_front;
				// array_pop($now_throw_front);
				// $seat_list->throw_front=$now_throw_front;//删除最后一个牌

				$seat_list->$seatkey= $this->sortBy($next_pai);
				$now_present_gang = ++$present_gang;
				$seat_list->waiter_doing=array();//清空
				$seat_list->gang = array($throw_seatid=>$now_present_gang);
				$seat_list->player_action=array('gang'=>$throw_seatid);//自己摸牌杠的还是拿别人的牌杠的
				$upsert["$seatkey"]=  json_encode($seat_list);
				$this->redis->hMSet(self::INFO_KEY . $this->id,$upsert);

				$game_info = array('type'=>array($seatid=>array(5=>array())));
				$this->retention($game_info);
				$remind =array(
					'canTouch'=>2,
					'seatid'=>$seatid,
				);



				Socket::sendToChannel("game-{$this->id}","Pushment","remind",$remind);
			//end

			return true;
		}elseif($throwType==2){//自摸
			$satisfy_ok =array();
			$throw_seatid =$seatid;
			$deskcards = $room['desk_majiang'];
			$deskcards_arr=json_decode($deskcards);
			$player_action=$myhandspai['player_action'];
			//自己摸牌
			$dachu = $room['dachu'];
			$dachu =json_decode($dachu);
			$flowers =$this->getFlowers($dachu);
			$allgang=$this->getallgang($room);
			$gang_total=$allgang*2;//当前所有杠的数量
			$isExists_gang =isset($player_action['gang'])?2:1;
			$basic_number = $flowers<8?14+$gang_total:16+$gang_total;
			if($isExists_gang==2){//本人有杠
				//杠开
				$gang_somebody=$player_action['gang'];
				if($gang_somebody==$user['seatid']){
					array_push($satisfy_ok, 9);
				}else{
					array_push($satisfy_ok, 10);// 送杠胡
				}
				
			}
			array_push($satisfy_ok, 6);
			//如果手牌只有一张的时候就是大吊
			if($prevpai==1){
				array_push($satisfy_ok, 7);
			}
			//海底捞月
			$left_numbers = count($deskcards_arr);//当前牌的数量
			if($left_numbers==$basic_number){
				array_push($satisfy_ok, 17);
			}
			$seat_offer =$myhandspai;
			$seat_offer['isHu']=2;
			$upsert["$seatkey"]=  json_encode($seat_offer);
			$this->redis->hMSet(self::INFO_KEY . $this->id, $upsert); 
			//算分
				$double =$room['double'];//倍数
				$aResult=$this->sumscore($seatid,$pai,$throw_seatid,$satisfy_ok);
				//拉杠
				$lagang =1;
				$songgang=1;
				if(in_array(11,$tai_type)){
					$lagang=2;
				}
				if(in_array(10,$tai_type)){
					$songgang=2;
				}
				$scorelist =array();
				for($i=1;$i<=4;$i++){
					$seatkey ='seat'.$i;
					$seatinfo = $room[$seatkey];
					$uid =$seatinfo['uid'];
					$mUser = new UserModel($uid);
					$info=$mUser->getUserInfoByUid();
					$nickname =isset($info['nickname'])?$info['nickname']:'';
					$headimgurl =isset($info['headimgurl'])?$info['headimgurl']:'';
					$basic_score = $double*$aResult['all_taishu'];
					if($i==$seatid){
						$front_pai =is_array($seatinfo['front'])? $seatinfo['front']:array();
						$front_pai = $this->changeFrontPai($front_pai);
						LOG::DEBUG('frontpai'.json_encode($frontpai));
						$handpai =$this->clearFlower($seatinfo[$seatkey]);
						if($lagang==2|| $songgang==2){
							$score = 5*$basic_score;
						}else{
							$score= $basic_score;
						}
					}
					if($i!=$seatid){
						$score = -$basic_score;
						// if($lagang==2||$songgang==2){
						// 	$score =-5*$basic_score;
						// }else{
						// 	$score = -$basic_score;
						// }
					}

					$scorelist[$i]=array(
							'nickname'=>$nickname,
							'headimgurl'=>$headimgurl,
							'score'=>$score,
							'pai'=>$pai,
							'basic_score'=>$basic_score,
						);
				}
				$result = $this->sanbao($seatid,$throw_seatid);
				if(is_array($result)&&$result){
					if(key($result)==1){
						//自摸
						$re_value=current($result);
						$first_key = array_shift($re_value);
						$scorelist[$seatid]['score']=$scorelist[$seatid]['score']+5*$scorelist[$seatid]['basic_score'];
						$scorelist[$first_key]['score']=$scorelist[$first_key]['score']-5*$scorelist[$first_key]['basic_score'];

					}elseif(key($result)==2){
						$re_value=current($result);
						$first_key = array_shift($re_value);
						$scorelist[$seatid]['score']=$scorelist[$seatid]['score']+2*$scorelist[$seatid]['basic_score'];
						$scorelist[$throw_seatid]['score']=$scorelist[$throw_seatid]['score']-2*$scorelist[$throw_seatid]['basic_score'];
					}elseif(key($result)==3){
						$re_value=current($result);
						$first_key = array_shift($re_value);
						$scorelist[$seatid]['score']=$scorelist[$seatid]['score']+2*$scorelist[$seatid]['basic_score'];
						$scorelist[$throw_seatid]['score']=$scorelist[$throw_seatid]['score']-$scorelist[$throw_seatid]['basic_score'];
						$scorelist[$first_key]['score']=$scorelist[$first_key]['score']-$scorelist[$first_key]['basic_score'];
					}
				}
				$result=$this->hubao($seatid,$throw_seatid);
				if(is_array($result)&&$result){
					if(key($result)==1){
						//自摸
						$re_value=current($result);
						$first_key = array_shift($re_value);
						$scorelist[$seatid]['score']=$scorelist[$seatid]['score']+10*$scorelist[$seatid]['basic_score'];
						$scorelist[$first_key]['score']=$scorelist[$first_key]['score']-10*$scorelist[$first_key]['basic_score'];

					}elseif(key($result)==2){
						$re_value=current($result);
						$first_key = array_shift($re_value);
						$scorelist[$seatid]['score']=$scorelist[$seatid]['score']+4*$scorelist[$seatid]['basic_score'];
						$scorelist[$throw_seatid]['score']=$scorelist[$throw_seatid]['score']-4*$scorelist[$throw_seatid]['basic_score'];
					}elseif(key($result)==3){
						$re_value=current($result);
						$first_key = array_shift($re_value);
						$scorelist[$seatid]['score']=$scorelist[$seatid]['score']+3*$scorelist[$seatid]['basic_score'];
						$scorelist[$throw_seatid]['score']=$scorelist[$throw_seatid]['score']-$scorelist[$throw_seatid]['basic_score'];
						$scorelist[$first_key]['score']=$scorelist[$first_key]['score']-2*$scorelist[$first_key]['basic_score'];
					}
				}
				$pai_list[] =array(
							'front_pai'=>$front_pai,
							'handpai'=>$handpai,
							'pai_type'=>$aResult['aList'],
							'all_taishu'=>$aResult['all_taishu'],
							'pai'=>is_array($pai)?current($pai):$pai,
						);
				$list['pai_list'] = $pai_list;
				$list['scorelist'] = $scorelist;
				$this->changeUserScore($scorelist);
				$game_info =array('type'=>array($seatid=>array(7=>array())));
				$this->retention($game_info);
				Socket::sendToChannel("game-{$this->id}", "Pushment", "over", $list);
			//end



			return true;
		}elseif($throwType==3){
			//过
			if($seatid==4){
				$next_seatid=1;
			}else{
				$next_seatid=$seatid+1;
			}
			$remind =array(
					'canTouch'=>2,
					'seatid'=>$next_seatid,
				);
			//提醒出牌人出牌成功
			// $lead =array('lead'=>2,'pai'=>$pai,'seatid'=>$now_seatid);
			// foreach($user_uid as $uid){
			// 	Socket::sendToUser($uid,"Pushment","lead",$lead);
			// }
			$game_info =array('type'=>array($next_seatid=>array(5=>array())));
			$this->retention($game_info);
			Socket::sendToChannel("game-{$this->id}","Pushment","remind",$remind);
		}else{

		}
		
		// $this->_error=json_encode($myhandspai);
		// return false;
		// 从我的手牌仍出去
		$this->removePai($myhandspai,$pai,$seatkey,$seatid,$room);
		if($seatid==4){
			$next_seatid=1;
		}else{
			$next_seatid=++$seatid;
		}
		$seatmykey="seat".$next_seatid;//下家
		$next_user = $room[$seatmykey];
		$next_pai = $next_user[$seatmykey];
		//是否可以杠 碰
		$now_seatid= $user['seatid'];
		$dataResult =array();
		$someonecantouch = true;
		$user_uid =array();
		$guo_numbers =0;//可以过的次数
		for($i=1;$i<=4;$i++){
			$seatmykey ='seat'.$i;
			$next_user = $room[$seatmykey];

			$user_uid[]=$next_user['uid'];
			if($i==$now_seatid) {
				$list[$next_user['uid']]=array(
						'seatid'=>$i,
						'throw_seatid'=>$now_seatid,
						'pai'=>$pai,
						'eat'=>1,
						'peng'=>1,
						'gang'=>1,
						'hu'=>1,
					);

				continue;//当前玩家
			}
			
			$next_pai = $next_user[$seatmykey];
			$myfront =isset($next_user['front'])?$next_user['front']:'';
			//吃 只有下家可以吃
			$is_eat=1;
			if($pai<31 && $i==$next_seatid){
				$isEat=$this->findEat($next_pai,$pai);
				$is_eat =$isEat?2:1;
			}
			$is_gang= $this->findPai($next_pai,$pai);
			$is_peng= $this->findPengPai($next_pai,$pai);
			$gang =$is_gang?2:1;
			$peng =$is_peng?2:1;
			$handscards =$next_pai;
			array_push($handscards, $pai);
			sort($handscards);
			$isHu =$this->basicHu($handscards);
			$hu =$isHu?2:1;
			if($hu==2){
				//判断是否有台数
				$aResult_cur = $this->sumscore($i,array($pai),$throw_seatid);
				if(!$aResult_cur['all_taishu']){
					Log::DEBUG('总台数切换'.$aResult_cur['all_taishu']);
					$hu =1;
				}else{
					Log::DEBUG("拿的牌".$pai.'胡牌_座位'.$seatmykey.json_encode($handscards));
				}
				
			}
			$combox_eat_pai=array();
			$combox_peng_pai=array();
			$combox_gang_pai=array();
			//判断front是否3张
			$now_gang = $this->selfTouch($myfront,$next_pai);

			if($peng==2 && $hu==1) {
				$pai_arr =array($pai,$pai,$pai);
				$combox_peng_pai[] = implode(',', $pai_arr);
			}
			if($gang==2 && $hu==1) {
				$pai_arr =array($pai,$pai,$pai,$pai);
				$combox_gang_pai[] = implode(',', $pai_arr);
				if(is_array($now_gang)&&$now_gang){
					$peng=2;
					foreach ($now_gang as $key => $pengs) {
						$this_pengpai =array($pegns,$pegns,$pegns);
						$combox_peng_pai[]=implode(',',$this_pengpai);
					}
				}
			}
			if($is_eat==2 && $hu==1){
				$combox_eat_pai=$this->findEatPai($next_pai,$pai);				
			}
			$combox_game_info=array();
			if($is_eat==2){
				$combox_game_info = array(1=>array('pai'=>is_array($pai)?current($pai):$pai,'list_pai'=>$combox_eat_pai,'throw_seatid'=>$user['seatid']));
			}
			if($peng==2){
				$combox_game_info = array(2=>array('pai'=>is_array($pai)?current($pai):$pai,'list_pai'=>$combox_peng_pai,'throw_seatid'=>$user['seatid']));
			}
			if($gang==2){
				$combox_game_info = array(3=>array('pai'=>is_array($pai)?current($pai):$pai,'list_pai'=>$combox_gang_pai,'throw_seatid'=>$user['seatid']));
			}
			if($hu==2){
				$combox_game_info = array(4=>array('pai'=>is_array($pai)?current($pai):$pai,'throw_seatid'=>$user['seatid']));
			}
			$game_info[$i] =array(
					'type'=> $combox_game_info,
				);

			$list[$next_user['uid']]  = array(
					'seatid'=>$i,
					'throw_seatid'=>$now_seatid,
					'pai'=>$pai,
					'eat'=>$is_eat,
					'peng'=>$peng,
					'gang'=>$gang,
					'hu'=>$hu,
					'combox_eat_pai'=>$combox_eat_pai,
					'combox_peng_pai'=>$combox_peng_pai,
					'combox_gang_pai'=>$combox_gang_pai,
				);
			if($is_eat==2 || $peng==2 ||$gang==2 ||$hu==2){
				$guo_numbers++;
				$someonecantouch=false;
			}
			if($hu==2){
				$hu_order[] = $i;
			}
		}
		if($guo_numbers){
			$hu_order =array();
			$now_guo_order = array(intval($pai)=>$guo_numbers);

			$guo_org =isset($room['guo_order'])?$room['guo_order']:'';
			if($guo_org){
				$guo_org =json_decode($guo_org,true);
				$all_arr = $guo_org;
			}
			$all_arr[]= $now_guo_order;
			$upsert['guo_order']= json_encode($all_arr);
			$upsert['check_order'] =json_encode($all_arr);
			$upsert['hu_order'] =json_encode($hu_order);
			$this->redis->hMSet(self::INFO_KEY . $this->id,$upsert);
		}
		//如果提交不成立 就可以摸牌		
		if($someonecantouch){
			$remind =array(
					'canTouch'=>2,
					'seatid'=>$next_seatid,
				);
			$game_info = array(
				$next_seatid=> array(
						'type'=>array(5=>array()),
					),
			);
			$this->retention($game_info);

			//提醒出牌人出牌成功
			$lead =array('lead'=>2,'pai'=>$pai,'seatid'=>$now_seatid);
			foreach($user_uid as $uid){
				Socket::sendToUser($uid,"Pushment","lead",$lead);
			}
			
			Socket::sendToChannel("game-{$this->id}","Pushment","remind",$remind);
		}else{


			$this->retention($game_info);

			foreach($user_uid as $uid){
				//if($uid == $user['uid']) continue;

				//file_put_contents('uid.txt',json_encode($list[$uid]).PHP_EOL,FILE_APPEND);

				Socket::sendToUser($uid,"Pushment","shots",$list[$uid]);
			}
		}
		return true;
	}
	/**
	 *单局结束 踢出某人座位
	 * [kick description]
	 * @return [type] [description]
	 */
	public function kick(){
		$user =$this->mUser->getInfo();
		$room = $this->getInfo();
		$seatid = $user['seatid'];
		$kick_list = isset($room['kick_user'])?$room['kick_user']:'';
		$kick_user_arr=array();
		if($kick_list){
			array_push($kick_list,$seatid);
		}else{
			$kick_user_arr = array($seatid);
		}
		$room['kick_user']=json_encode($kick_user_arr);
		$this->redis->hMSet(self::INFO_KEY .$this->id,$room);
		return true;
	}
	/**
	 *  最近战况
	 * [fight description]
	 * @return [type] [description]
	 */
	public function fight(){
		$uid = $this->mUser->getUid();
		$room = $this->getInfo();
		$mMatch = new MatchModel($uid);
		$latestMatch = $mMatch->getall($this->id);
		$watcher =isset($room['watcher'])?$room['watcher']:'';
		$new_watcher =array();
		$watcher =json_decode($watcher,true);
		if(is_array($watcher)&&$watcher){
			foreach ($watcher as $uid => $value) {
				$mUser = new UserModel($uid);			
				$userinfo = $mUser->getInfo();
				$new_watcher[]=array(
						'nickname'=>$userinfo['nickname'],
						'uid'=>$uid,
					);
			}
		}
		for($i=1;$i<=4;$i++){
			$seatkey="seat".$i;
			$cur_seatinfo = $room[$seatkey];
			$uid  =$cur_seatinfo['uid'];
			if(!$uid) continue;
			$mUser = new UserModel($uid);			
			$userinfo = $mUser->getInfo();
			$score = $this->getScoreByUid($latestMatch,$uid);
			$actual_list[]=array(
					'nickname'=>$userinfo['nickname'],
					'score'=>$score,
				);
		}
		$actual_list=array(
				'watcher'=>$new_watcher,
				'seats'=>$actual_list,
			);
		return  array('actual_list'=>json_encode($actual_list));
	}
	private function getScoreByUid($latestMatch,$uid){
		$total =0;
		if(is_array($latestMatch)&& $latestMatch){
			foreach ($latestMatch as $key => $value) {
				foreach ($value as $uidlist => $vv) {
					if($uidlist==$uid){
						$total+=$vv['score'];
					}
				}
			}
		}
		return $total;
	}
	public function changeUserScore($new_list){
		//if(!$list) return;
		$room = $this->getInfo();
		$player=array();
		Log::DEBUG('积分列表',json_encode($new_list));
		if(is_array($new_list)&&$new_list){
			foreach ($new_list as $seatid => $value) {
				$seatkey="seat".$seatid;
				$seatInfo =$room[$seatkey];
				$myuid =$seatInfo['uid'];
				$mUser =new UserModel($myuid);
				$userinfo =$mUser->getInfo();
				$userinfo['point'] = $userinfo['point']+$value['score'];
				if($value['score']>0){
					$userinfo['victory']=$userinfo['victory']+1;
				}
				$mUser->save($userinfo);
				$player[] =array(
						'score'=>$value['score'],
						'uid'=>$myuid,
						'nickname'=>$userinfo['nickname'],
					);
			}
			//保存本局的信息
			$uid = $this->mUser->getUid();
			$mMatch = new MatchModel($uid);
			$mMatch->saveActual($room,$player);
		}
		//添加比赛记录
		if(is_array($player)&&$player){
			foreach($player as $v){
				$uid = $v['uid'];
				$mMatch = new MatchModel($uid);
				$mMatch->saveUserMatch($room,$player);
			}
		}
		//clear roominfo
		//清除上把游戏信息
		$kick_user = isset($room['kick_user'])?$room['kick_user']:'';
		$kick_arr_list=array();
		if($kick_user){
			foreach($kick_user as $kick_seatid){
				$seatkey ="seat".$kick_seatid;
				$kick_arr_list[]=$seatkey;
			}
		}

		$room['desk_majiang']='';
		$room['dachu']='';
		$room['left_pai']='';
		$room['guo_order']='';
		$room['throw_order']='';
		$room['check_order']='';
		$room['state']=0;
		$room['hu_order']='';
		$room['kick_user']='';
		$room['game_info']='';
		$room['pan']=$room['pan']+1;
		for($i=1;$i<=4;$i++){
			if($kick_arr_list && in_array($i,$kick_arr_list)) continue;
			$seatkey ="seat".$i;
			$cur_seatinfo =$room[$seatkey];
			$room[$seatkey]=json_encode(array(
					'uid'=>$cur_seatinfo['uid'],
					'seatid'=>$cur_seatinfo['seatid'],
					'state'=>0,
					'point'=>$cur_seatinfo['point'],
				));
		}
		$this->redis->hMSet(self::INFO_KEY . $this->id,$room);

	}
	private function getallgang($room){
		$total=$this->getgangs($room,"seat1");
		$total+=$this->getgangs($room,"seat2");
		$total+=$this->getgangs($room,"seat3");
		$total+=$this->getgangs($room,"seat4");
		return $total;
	}
	private function getgangs($room,$seatid){
		$seatInfo =$room[$seatid];
		$gangInfo = isset($seatInfo['gang'])?$seatInfo['gang']:0;
		$total =0;
		if(is_array($gangInfo)&&$gangInfo){
			foreach($gangInfo as $nextv){
				$total+=intval($nextv);
			}
		}
		return $total;
	}
	private function removePai($cur_pai,$pai,$seatkey,$seatid,$room){		
		if(is_array($cur_pai)&&$cur_pai){
			foreach ($cur_pai as $key => $value) {
				if($value==$pai){
					unset($cur_pai[$key]);
					break;
				}
			}
		}
		$seat_list = $this->redis->hGet(self::INFO_KEY.$this->id,$seatkey);
		$seat_list =json_decode($seat_list);
		$throw_front=$seat_list->throw_front;//现在的扔掉的牌		
		$latest =$throw_front?array_merge($throw_front,array($pai)):array($pai);
		$seat_list->throw_front=$latest;
		$seat_list->waiter_doing=array($pai);//加入牌 等待玩家吃 碰 杠 胡 
		$seat_list->$seatkey=$this->sortBy($cur_pai);
		$upsert["$seatkey"]=  json_encode($seat_list);

		$now_throw_order = array(intval($pai)=>$seatid);

		$throw_order_org =isset($room['throw_order'])?$room['throw_order']:'';
			if($throw_order_org){
				$throw_order_org =json_decode($throw_order_org,true);
				$all_arr = $throw_order_org;
			}
			$all_arr[]= $now_throw_order;
			$upsert['throw_order']= json_encode($all_arr);

		$this->redis->hMSet(self::INFO_KEY . $this->id,$upsert);
	}

	private function  userWeight($remind,$operation,$info,$type){
		$this->lock();
		$order = $this->redis->hGetAll(self::PLAYER_ORDER . $this->id);
		if(isset($order['order'])&&$order['order']){
			$redis_order = json_decode($order['order'],true);
			$redis_order[] =  array(
						$type =>array(
								'remind'=>$remind,
								'operation'=>$operation,
								'info'=>$info,
							),
					);
			$order['order']=json_encode($redis_order);
			$this->redis->hMSet(self::PLAYER_ORDER . $this->id,$order);
		}else{
				$combox[] = array(
						$type =>array(
								'remind'=>$remind,
								'operation'=>$operation,
								'info'=>$info,
							),
					);
				$order['order'] =json_encode($combox);
				$this->redis->hMSet(self::PLAYER_ORDER . $this->id,$order);
		}
		$this->unlock();

	}
	private function changeEat($new_chi_pai,$eat_pai){
		$new_chi_pai_all=array();
		foreach($new_chi_pai as $next){
			if($next!=$eat_pai){
				$new_chi_pai_all[]=$next;
			}
		}
		return $new_chi_pai_all;
	}
	/**
	 * xxx请注意，您已经被xxx吃了两口”；同家吃碰三下，会有toast文字提示“xxx与xxx做生意”
	 */
	private function eatTwoEat($seatid,$throw_seatid){
		$room = $this->getInfo();
		$seatkey ="seat".$seatid;
		$throwseatkey="seat".$throw_seatid;
		$seatinfo = $room[$seatkey];
		$throw_seatinfo = $room[$throwseatkey];
		$myuid =$seatinfo['uid'];
		$throw_uid =$throw_seatinfo['uid'];
		$present_eat = 0;
		$present_eat_arr = isset($seatinfo['eat'])? $seatinfo['eat']:null;
		if($present_eat_arr){
			$present_eat = isset($present_eat_arr[$throw_seatid])?intval($present_eat_arr[$throw_seatid]):0;
		}
		$result =array('enough'=>1);
		if($present_eat==1){
			$mUser =new UserModel($myuid);
			$myUser = $mUser->getInfo();
			$throwmUser =new UserModel($throw_uid);
			$throwUser = $throwmUser->getInfo();			
			$result =array('enough'=>2,'tips'=>$throwUser['nickname']."请注意，您已经被".$myUser['nickname']."吃了两口");
		}
		return $result;
	}
	private function eatThreeEatPeng($seatid,$throw_seatid){
		$room = $this->getInfo();
		$seatkey ="seat".$seatid;
		$throwseatkey="seat".$throw_seatid;
		$seatinfo = $room[$seatkey];
		$throw_seatinfo = $room[$throwseatkey];
		$myuid =$seatinfo['uid'];
		$throw_uid =$throw_seatinfo['uid'];
		$present_eat = 0;
		$present_peng =0;
		$present_eat_arr = isset($seatinfo['eat'])? $seatinfo['eat']:null;
		$present_peng_arr = isset($seatinfo['peng'])? $seatinfo['peng']:null;
		$present_gang_arr = isset($seatinfo['gang'])? $seatinfo['gang']:null;
		if($present_eat_arr){
			$present_eat = isset($present_eat_arr[$throw_seatid])?intval($present_eat_arr[$throw_seatid]):0;
		}
		if($present_peng_arr){
			$present_peng = isset($present_peng_arr[$throw_seatid])?intval($present_peng_arr[$throw_seatid]):0;
		}
		if($present_gang_arr){
			$present_gang = isset($present_gang_arr[$throw_seatid])?intval($present_gang_arr[$throw_seatid]):0;
		}
		//反向
		$result =array('enough'=>1);
		$all_eat_peng_gang=$present_eat+$present_peng+$present_gang;
		if($all_eat_peng_gang ==2 ){
			$mUser =new UserModel($myuid);
			$myUser = $mUser->getInfo();
			$throwmUser =new UserModel($throw_uid);
			$throwUser = $throwmUser->getInfo();	
			$result =array('enough'=>3,'tips'=>$throwUser['nickname']."与".$myUser['nickname']."做生意");
		}
		return $result;
	}
	//吃 碰 杠 胡 $pai是数组 
	public function dealPai($pai,$type){
		$uid = $this->mUser->getUid();
		$user = $this->mUser->getInfo();
		$seatid =$user['seatid'];
		$seatkey='seat'.$user['seatid'];
		$room = $this->getInfo();
		$checkinfo=$this->redis->hGetAll(self::PLAYER_ORDER . $this->id);
		$checkorder =json_decode($checkinfo['order'],true);
		$hasClick=0;
		if(is_array($checkorder)&&$checkorder){
			foreach($checkorder as $next){
				foreach($next as $nnext){
					$remind =$nnext['remind'];
					if($remind['seatid']==$seatid){
						$hasClick++;
						break 2;
					}
				}
			}
		}
		if($hasClick>0){
			$this->_error="对不起,已经操作过了.";
			return false;
		}


		$throw_order =isset($room['throw_order'])?$room['throw_order']:'';
		if(!$throw_order){
			$this->_error="没有牌可以吃碰杠胡";
			return false;
		}
		$throw_order =json_decode($throw_order,true);
		$throw_seatid= array_pop($throw_order);//删除当前打出的牌
		$throw_seatid= is_array($throw_seatid)?current($throw_seatid):$throw_seatid;
		$next_user = $room[$seatkey];
		$next_pai = $next_user[$seatkey];//当前玩家的牌
		if($type<=4 && $throw_seatid!=$seatid){
			$throw_seatid_now="seat".$throw_seatid;
			$throw_user =$room[$throw_seatid_now];
			$waiter_doing = $throw_user['waiter_doing'];
			//获取最后一张牌
			if(!$waiter_doing){
				$this->_error="没有牌可以吃碰杠";
				return false;
			}			
			$last_value = array_shift($waiter_doing);
			$cur_pai_arr = explode(",", $pai);
			if(!in_array($last_value,$cur_pai_arr)){
				$this->_error="没有牌可以吃碰杠";
				return false;
			}
		}
		switch ($type) {
			case 1:
				//吃
				//判断当前玩家吃碰杠几次 eat peng gang
				$eat=isset($next_user['eat'])?$next_user['eat']:0;
				$peng=isset($next_user['peng'])?$next_user['peng']:0;
				$gang=isset($next_user['gang'])?$next_user['gang']:0;
				$all_action =0;
				if(is_array($eat)&&$eat){
					foreach($eat as $nextv){
						$all_action+=intval($nextv);
					}
				}
				if(is_array($peng)&&$peng){
					foreach($peng as $nextv){
						$all_action+=intval($nextv);
					}
				}
				if(is_array($gang)&&$gang){
					foreach($gang as $nextv){
						$all_action+=intval($nextv);
					}
				}
				if($next_pai){
					$chi_pai = explode(",", $pai);
					$counts=0;
					$new_chi_pai=array();
					foreach($chi_pai as $thiskey=>$next){
						$new_chi_pai[]=intval($next);
						if(in_array($next,$next_pai)){
							$counts++;
						}
					}
				}
				if($counts<2){
					$this->_error='吃牌牌型错误.';
					return false;
				}
				$next_pai[] = $last_value; //加入吃的牌
				$current_chi_pai=$new_chi_pai;
				foreach($next_pai as $key=>$next){
					if(in_array($next,$current_chi_pai)){
						unset($next_pai[$key]);
						$current_chi_pai = $this->changeEat($current_chi_pai,$next);				
					}
				}
				$next_pai =$this->sortBy($next_pai);
				$throwpai =array();
				if($all_action<2){
					//吃的牌和边牌不能打出 //last_value
					sort($chi_pai);
					$endpai=array_pop($chi_pai);
					$begpai=array_shift($chi_pai);
					if(!in_array($endpai,array(9,19,29)) && $endpai<31){
						$noallow_end =$endpai+1;
					}
					if(!in_array($begpai,array(1,11,21)) && $endpai<31 ){
						$noallow_beg=$begpai-1;
					}
					array_push($throwpai,$last_value);
					if(in_array($noallow_beg,$next_pai)){
						array_push($throwpai, $noallow_beg);
					}
					if(in_array($noallow_end,$next_pai)){
						array_push($throwpai, $noallow_end);
						sort($throwpai);
					}
				}

				//$next_seatid =$seatid==4?1:++$seatid;
				$remind =array(
					'canTouch'=>1,
					'seatid'=>$seatid,
					'throwpai'=>$throwpai,
				);
				$operation =array(
						'seatid'=>$seatid,
						'throw_seatid'=>$throw_seatid,
						'pai'=>$last_value,
						'combox_pai'=>$new_chi_pai,
						'next_pai'=>$next_pai,
						'type'=>1,
					);
				$info =array(
						'seatkey'=>$seatkey,
						'throw_seatid'=>$throw_seatid,
						'action'=>'eat',
						'new_pai'=>$new_chi_pai,
						'next_pai'=>$next_pai,
					);
				//Socket::sendToChannel("game-{$this->id}","Pushment","operation",$operation);
				//Socket::sendToChannel("game-{$this->id}","Pushment","remind",$remind);
				$this->userWeight($remind,$operation,$info,1);

				$this->clearGameInfo($seatid);

				//$this->_error=json_encode($next_pai);
				Log::DEBUG($seatid.'吃'."remind".json_encode($remind).'operation'.json_encode($operation).'info'.json_encode($info));
				break;
			case 2:
				//碰
				if($next_pai){
					$peng_pai = explode(",", $pai);
					$counts=0;
					$pengOne=isset($peng_pai[0])?intval($peng_pai[0]):0;
					foreach($next_pai as $thiskey=>$next){
					
						if($next==$pengOne){
							$counts++;
						}
					}
				}
				if($counts<2){
					$this->_error='碰牌牌型错误.';
					return false;
				}
				$front_peng=0;
				foreach($next_pai as $key=>$next){
					if($next==$pengOne){
						++$front_peng;
						unset($next_pai[$key]);
					}
					if($front_peng==2) break;
				}
				$new_peng_pai=array($pengOne,$pengOne,$pengOne);
				

				$remind =array(
					'canTouch'=>1,
					'seatid'=>$seatid,
				);
				$operation =array(
						'seatid'=>$seatid,
						'throw_seatid'=>$throw_seatid,
						'pai'=>$last_value,
						'combox_pai'=>$new_peng_pai,
						'type'=>2,
					);
				$info =array(
						'seatkey'=>$seatkey,
						'throw_seatid'=>$throw_seatid,
						'action'=>'peng',
						'new_pai'=>$new_peng_pai,
						'next_pai'=>$next_pai,
					);
				$this->userWeight($remind,$operation,$info,2);
				$this->clearGameInfo($seatid);
				//Socket::sendToChannel("game-{$this->id}","Pushment","operation",$operation);

				Log::DEBUG($seatid.'碰'."remind".json_encode($remind).'operation'.json_encode($operation).'info'.json_encode($info));
				//Socket::sendToChannel("game-{$this->id}","Pushment","remind",$remind);				
				break;
			case 3:
				//杠
				if($next_pai){
					$gang_pai = explode(",", $pai);
					$counts=0;
					$gangOne=isset($gang_pai[0])?intval($gang_pai[0]):0;
					foreach($next_pai as $thiskey=>$next){
					
						if($next==$gang_pai[0]){
							$counts++;
						}
					}
				}
				if($counts!=3){
					$this->_error='杠牌牌型错误.';
					return false;
				}
				foreach($next_pai as $key=>$next){
					if($next==$gangOne){
						unset($next_pai[$key]);
					}
				}
				$new_gang_pai=array($gangOne,$gangOne,$gangOne,$gangOne);
				//$next_seatid =$seatid==4?1:++$seatid;
				$remind =array(
					'canTouch'=>2,
					'seatid'=>$seatid,
				);
				$operation =array(
						'seatid'=>$seatid,
						'throw_seatid'=>$throw_seatid,
						'pai'=>$last_value,
						'combox_pai'=>$new_gang_pai,
						'type'=>3,
					);
				$info =array(
						'seatkey'=>$seatkey,
						'throw_seatid'=>$throw_seatid,
						'action'=>'gang',
						'new_pai'=>$new_gang_pai,
						'next_pai'=>$next_pai,
					);
				$this->clearGameInfo($seatid);
				//Socket::sendToChannel("game-{$this->id}","Pushment","operation",$operation);
				//Socket::sendToChannel("game-{$this->id}","Pushment","remind",$remind);
				$this->userWeight($remind,$operation,$info,3);
				Log::DEBUG($seatid.'杠'."remind".json_encode($remind).'operation'.json_encode($operation).'info'.json_encode($info));
				break;
			case 4:
				# 胡 结算牌分
				$double =$room['double'];//倍数
				$this->lock();
				$aResult=$this->sumscore($seatid,$pai,$throw_seatid);
				$this->unlock();
				Log::DEBUG("座位".$seatid."牌".$pai."仍牌".$throw_seatid."数据".json_encode($aResult));
				//拉杠
				$lagang =1;
				if(in_array(11,$satisfy_ok)){
					$lagang=2;
				}
				$scorelist =array();
				for($i=1;$i<=4;$i++){
					$score =0;
					$seatkey ='seat'.$i;
					$seatinfo = $room[$seatkey];
					$uid =$seatinfo['uid'];
					$mUser = new UserModel($uid);
					$info=$mUser->getUserInfoByUid();
					$nickname =isset($info['nickname'])?$info['nickname']:'';
					$headimgurl =isset($info['headimgurl'])?$info['headimgurl']:'';
					$basic_score = $double*$aResult['all_taishu'];
					if($i==$seatid){
						$front_pai = is_array($seatinfo['front'])? $seatinfo['front']:array();
						$front_pai =$this->changeFrontPai($front_pai);
						$handpai =$this->clearFlower($seatinfo[$seatkey]);
						Log::DEBUG('胡牌人手牌:'.json_encode($handpai));
						if($lagang==2){
							$score = 5*$basic_score;
						}else{
							$score= $basic_score;
						}
					}
					if($i==$throw_seatid){
						if($lagang==2){
							$score =-5*$basic_score;
						}else{
							$score = -$basic_score;
						}
					}

					$scorelist[$i]=array(
							'nickname'=>$nickname,
							'headimgurl'=>$headimgurl,
							'score'=>$score,
							'pai'=>$pai,
							'basic_score'=>$basic_score,
							'throw_seatid'=>$throw_seatid,
						);
				}
				$result = $this->sanbao($seatid,$throw_seatid);
				if(is_array($result)&&$result){
					if(key($result)==1){
						//自摸
						$re_value=current($result);
						$first_key = array_shift($re_value);
						$scorelist[$seatid]['score']=$scorelist[$seatid]['score']+5*$scorelist[$seatid]['basic_score'];
						$scorelist[$first_key]['score']=$scorelist[$first_key]['score']-5*$scorelist[$first_key]['basic_score'];

					}elseif(key($result)==2){
						$re_value=current($result);
						$first_key = array_shift($re_value);
						$scorelist[$seatid]['score']=$scorelist[$seatid]['score']+2*$scorelist[$seatid]['basic_score'];
						$scorelist[$throw_seatid]['score']=$scorelist[$throw_seatid]['score']-2*$scorelist[$throw_seatid]['basic_score'];
					}elseif(key($result)==3){
						$re_value=current($result);
						$first_key = array_shift($re_value);
						$scorelist[$seatid]['score']=$scorelist[$seatid]['score']+2*$scorelist[$seatid]['basic_score'];
						$scorelist[$throw_seatid]['score']=$scorelist[$throw_seatid]['score']-$scorelist[$throw_seatid]['basic_score'];
						$scorelist[$first_key]['score']=$scorelist[$first_key]['score']-$scorelist[$first_key]['basic_score'];
					}
				}
				$result=$this->hubao($seatid,$throw_seatid);
				if(is_array($result)&&$result){
					if(key($result)==1){
						//自摸
						$re_value=current($result);
						$first_key = array_shift($re_value);
						$scorelist[$seatid]['score']=$scorelist[$seatid]['score']+10*$scorelist[$seatid]['basic_score'];
						$scorelist[$first_key]['score']=$scorelist[$first_key]['score']-10*$scorelist[$first_key]['basic_score'];

					}elseif(key($result)==2){
						$re_value=current($result);
						$first_key = array_shift($re_value);
						$scorelist[$seatid]['score']=$scorelist[$seatid]['score']+4*$scorelist[$seatid]['basic_score'];
						$scorelist[$throw_seatid]['score']=$scorelist[$throw_seatid]['score']-4*$scorelist[$throw_seatid]['basic_score'];
					}elseif(key($result)==3){
						$re_value=current($result);
						$first_key = array_shift($re_value);
						$scorelist[$seatid]['score']=$scorelist[$seatid]['score']+3*$scorelist[$seatid]['basic_score'];
						$scorelist[$throw_seatid]['score']=$scorelist[$throw_seatid]['score']-$scorelist[$throw_seatid]['basic_score'];
						$scorelist[$first_key]['score']=$scorelist[$first_key]['score']-2*$scorelist[$first_key]['basic_score'];
					}
				}
				$list =array(
							'front_pai'=>$front_pai,
							'handpai'=>$handpai,
							'pai_type'=>$aResult['aList'],
							'all_taishu'=>$aResult['all_taishu'],
							'pai'=>is_array($pai)?current($pai):$pai,
							'scorelist'=>$scorelist,
						);
				$this->userWeight($list,$throw_seatid,$seatid,4);
				$this->clearGameInfo($seatid);
				Log::DEBUG($seatid.'胡'."list".json_encode($list));
				break;	
			default:
				//过
				$guo_order = isset($room['guo_order'])?json_decode($room['guo_order'],true):'';
				if($guo_order){
					$last_value = array_pop($guo_order);
					$numbers = is_array($last_value)?current($last_value):$last_value;
					if($numbers>0){
						$reduce_number=$numbers-1;
						$guo_order[]=array(key($last_value)=>$reduce_number);
						$upsert['guo_order'] = json_encode($guo_order);
						$this->redis->hMSet(self::INFO_KEY . $this->id,$upsert);
					}
					//if($numbers==1){
						$new_seatid=$throw_seatid+1;
						$next_seatid =$throw_seatid==4?1:$new_seatid;
						$remind =array(
						'canTouch'=>2,
						'seatid'=>$next_seatid,
						);
						//Socket::sendToChannel("game-{$this->id}","Pushment","remind",$remind);
					//}
					
				}

				$operation =array(
						'seatid'=>$seatid,
						'throw_seatid'=>$throw_seatid,
						'pai'=>$last_value,
						'type'=>5,
					);
				$this->saveGuo($seatid,$throw_seatid,$pai,$room);

				$this->clearGameInfo($seatid);
				$this->userWeight($remind,$operation,'',5);
				//Socket::sendToChannel("game-{$this->id}","Pushment","operation",$operation);
				break;
		}
		$this->lastend($throw_seatid);
		return true;
	}
	public function saveGuo($seatid,$throw_seatid,$pai,$room){

		$guo_same_pai =isset($room['guo_same_pai'])?$room['guo_same_pai']:'';
		$guo_same_pai = json_decode($guo_same_pai,true);
		$guo_same_pai[$seatid]=array(
				'pai'=>$pai,
				'throw_seatid'=>$throw_seatid,
			);
		$upsert['guo_same_pai']=json_encode($guo_same_pai);
		$this->redis->hMSet(self::INFO_KEY . $this->id,$upsert);
	}
	public function lastend($throw_seatid){
		$order = $this->redis->hGetAll(self::PLAYER_ORDER . $this->id);
		$room =  $this->redis->hGetAll(self::INFO_KEY.$this->id);
		$hu_order = isset($room['hu_order'])?json_decode($room['hu_order'],true):'';
		$check_order = isset($room['check_order'])?json_decode($room['check_order'],true):'';
		if($check_order){
			$last_value = array_pop($check_order);
			$numbers = is_array($last_value)?current($last_value):$last_value;
		}
		Log::DEBUG('checkorder:'.json_encode($checkorder).PHP_EOL."order:".json_encode($order['order']));
		if(isset($order['order']) && $order['order']){
			$orderInfo = $order['order'];
			$this_orderInfo =json_decode($orderInfo,true);
			$type_order= array();
			file_put_contents('st.txt', $numbers.'||'.count($this_orderInfo));
			if($numbers!=count($this_orderInfo)){
				return true;
			}
			$hu_number= count($hu_order);//当前可以胡的人数
			$have_click=array();
			foreach($this_orderInfo as $next){
				foreach($next as $type_key=>$next_on){
					if($type_key==5) continue;
					if($type_key==4) array_push($have_click,$type_key);
					array_push($type_order,$type_key);
				}
			}
			// if($hu_number>1 && $hu_number!=count($have_click)){
			// 	return true;
			// }
			// if($hu_number>1){
			// 	while (true) {
			// 		$first_id =$throw_seatid==4?1:++$throw_seatid;
			// 		if(in_array($first_id,$hu_order)){
			// 			break;
			// 		}
			// 	}
			// }
			Log::DEBUG('type_order'.json_encode($type_order));
			if(!$type_order){
				//过
				
				$this_info=array();
				foreach($this_orderInfo as $next){
					foreach($next as $newkey=>$v){
							$this_info=$v;
							break;
					}
				}
				$remind =$this_info['remind'];
				$operation=$this_info['operation'];

				$game_info =array($remind['seatid']=>array('type'=>array(5=>array())));
				$this->retention($game_info);

				Log::DEBUG('选择过'.json_encode($remind).'operation,'.json_encode($operation));
				Socket::sendToChannel("game-{$this->id}","Pushment","operation",$operation);
				Socket::sendToChannel("game-{$this->id}","Pushment","remind",$remind);
			}else{
					sort($type_order);
					$l_key =array_pop($type_order);
					Log::DEBUG('选择'.$l_key);
					switch ($l_key) {
						case 4:
							$this_info=array();
							foreach($this_orderInfo as $next){
								foreach($next as $newkey=>$v){
									//类型是4并且优先最近的座位id
									//if($hu_number){
										if(intval($newkey)==4){
											$this_info[] = $v;
											//break;
										}
									//}
									// else{
									// 	if(intval($newkey)==4 && $v['info']==$first_id){
									// 		$this_info=$v;
									// 		break;
									// 	}
									// }
									
								}
							}
							$game_info_hu=array();
							$now_scorelist=array();
							if(is_array($this_info) && $this_info){
								foreach($this_info as $now_this_info){
									$now_list =$now_this_info['remind'];
									$hu_seatid_arr[]=$now_this_info['info'];
									$new_list[] = array(
											'front_pai'=>$now_list['front_pai'],
											'handpai'=>$now_list['handpai'],
											'pai_type'=>$now_list['pai_type'],
											'all_taishu'=>$now_list['all_taishu'],
											'pai'=>$now_list['pai'],
										);
									$receive_data =$now_list['scorelist'];
									foreach($receive_data as $now_seatid=>$v){
										$cur_score = $now_scorelist[$now_seatid]['score']+$v['score'];
										$now_scorelist[$now_seatid] = array(
												'nickname'=>$v['nickname'],
												'headimgurl'=>$v['headimgurl'],
												'score'=>$cur_score,
												'seatid'=>$now_seatid,
											);
									}
									$this->changeUserScore($receive_data);
									$game_info_hu[$now_this_info['info']]=array('type'=>array(4=>array('pai'=>$now_list['pai'],'throw_seatid'=>$now_this_info['operation'])));
								}
							}
							$list['pai_list'] = $new_list;
							$list['scorelist']=$now_scorelist;
							$this->retention($game_info_hu);
							//切换庄家
							sort($hu_seatid_arr);
							$hu_seatid =array_shift($hu_seatid_arr);
							$this->changeZhuang('',2,$hu_seatid);
							Socket::sendToChannel("game-{$this->id}", "Pushment", "over", $list);
							Log::DEBUG('最终处理胡'."list".json_encode($list));
							break;
						case 3:
							$this_info=array();
							foreach($this_orderInfo as $next){
								foreach($next as $newkey=>$v){
									if(intval($newkey)==3){
										$this_info=$v;
										break;
									}
								}
							}
							$remind =$this_info['remind'];
							$operation=$this_info['operation'];
							$info =$this_info['info'];
							//beg
							$relation=array();
							$seatkey=$info['seatkey'];
							$new_gang_pai =$info['new_pai'];
							$throw_seatid =$info['throw_seatid'];

							$out_result = $this->eatThreeEatPeng($remind['seatid'],$throw_seatid);
							if($out_result['enough']==3){
								$relation['enough']=3;
								$relation['tips'] =$result['tips'];
							}	

							$next_pai =$info['next_pai'];
							$seat_list = $this->redis->hGet(self::INFO_KEY.$this->id,$seatkey);
							$seat_list =json_decode($seat_list);
							$front_list = $seat_list->front;//?array_merge($seat_list->front,$new_gang_pai):$new_gang_pai;
							$present_gang =$seat_list->gang?$seat_list->gang->$throw_seatid:0;
							$front_list[]= implode(',', $new_gang_pai);

							$seat_list->front=$front_list;

							$now_throw_front = $seat_list->throw_front;
							array_pop($now_throw_front);
							$seat_list->throw_front=$now_throw_front;//删除最后一个牌

							$front_rule = $seat_list->front_rule;
							$front_rule[] = array(
										'gang'=> implode(',', $new_gang_pai),
										'pai'=>$operation['pai'],
										'throw_seatid'=>$throw_seatid,
									);
							$seat_list->front_rule = $front_rule;

							$seat_list->$seatkey= $this->sortBy($next_pai);
							$now_present_gang = ++$present_gang;
							$seat_list->waiter_doing=array();//清空
							$seat_list->gang = array($throw_seatid=>$now_present_gang);
							$seat_list->player_action=array('gang'=>$throw_seatid);//自己摸牌杠的还是拿别人的牌杠的
							$upsert["$seatkey"]=  json_encode($seat_list);
							$this->redis->hMSet(self::INFO_KEY . $this->id,$upsert);

							$game_info =array($remind['seatid']=>array('type'=>array(5=>array())));
							$this->retention($game_info);
							//end
							Socket::sendToChannel("game-{$this->id}","Pushment","operation",$operation);
							Socket::sendToChannel("game-{$this->id}","Pushment","remind",$remind);
							if(is_array($relation)&&$relation){
								Socket::sendToChannel("game-{$this->id}","Pushment","relation",$relation);
							}
							Log::DEBUG('杠|手牌'.json_encode($next_pai)."杠牌:".json_encode($new_gang_pai)."|operation".json_encode($operation).'remind|'.json_encode($remind));
							break;
						case 2:
							$this_info=array();
							foreach($this_orderInfo as $next){
								foreach($next as $newkey=>$v){
									if(intval($newkey)==2){
										$this_info=$v;
										break;
									}
								}
							}
							$remind =$this_info['remind'];
							$operation=$this_info['operation'];
							$info =$this_info['info'];
							//beg
							$relation=array();
							$seatkey=$info['seatkey'];
							$new_peng_pai =$info['new_pai'];
							$throw_seatid =$info['throw_seatid'];

							$out_result = $this->eatThreeEatPeng($remind['seatid'],$throw_seatid);
							if($out_result['enough']==3){
								$relation['enough']=3;
								$relation['tips'] =$result['tips'];
							}	

							$next_pai =$info['next_pai'];

							$seat_list = $this->redis->hGet(self::INFO_KEY.$this->id,$seatkey);
							$seat_list =json_decode($seat_list);
							$front_list = $seat_list->front;//?array_merge($seat_list->front,$new_peng_pai):$new_peng_pai;

							$front_list[] = implode(',', $new_peng_pai);
							$present_peng =$seat_list->peng?$seat_list->peng->$throw_seatid:0;
							$seat_list->front=$front_list;

							$now_throw_front = $seat_list->throw_front;
							array_pop($now_throw_front);
							$seat_list->throw_front=$now_throw_front;//删除最后一个牌

							$front_rule = $seat_list->front_rule;
							$front_rule[] = array(
										'peng'=> implode(',', $new_peng_pai),
										'pai'=>$operation['pai'],
										'throw_seatid'=>$throw_seatid,
									);
							$seat_list->front_rule = $front_rule;

							$seat_list->$seatkey= $this->sortBy($next_pai);
							$now_present_peng = ++$present_peng;
							$seat_list->waiter_doing=array();//清空
							$seat_list->peng = array($throw_seatid=>$now_present_peng);
							$seat_list->player_action=array('peng'=>$throw_seatid);
							$upsert["$seatkey"]=  json_encode($seat_list);
							$this->redis->hMSet(self::INFO_KEY . $this->id,$upsert);
							//end
							Socket::sendToChannel("game-{$this->id}","Pushment","operation",$operation);
							Socket::sendToChannel("game-{$this->id}","Pushment","remind",$remind);

							$game_info =array($remind['seatid']=>array('type'=>array(6=>array())));
							$this->retention($game_info);
							if(is_array($relation)&&$relation){
								Socket::sendToChannel("game-{$this->id}","Pushment","relation",$relation);
							}
							Log::DEBUG('碰|手牌'.json_encode($next_pai)."碰牌:".json_encode($new_peng_pai)."|operation".json_encode($operation).'remind|'.json_encode($remind));
							break;
						case 1:
							//吃
							$this_info=array();
							foreach($this_orderInfo as $next){
								foreach($next as $newkey=>$v){
									if(intval($newkey)==1){
										$this_info=$v;
										break;
									}
								}
							}
							$remind =$this_info['remind'];
							$operation=$this_info['operation'];
							$info =$this_info['info'];
							//beg
								$relation=array();
								$seatkey=$info['seatkey'];
								$new_chi_pai =$info['new_pai'];
								$throw_seatid =$info['throw_seatid'];
								$result = $this->eatTwoEat($remind['seatid'],$throw_seatid);
								if($result['enough']==2){
									$relation['enough']=2;
									$relation['tips'] =$result['tips'];
								}

								$out_result = $this->eatThreeEatPeng($remind['seatid'],$throw_seatid);
								if($out_result['enough']==3){
									$relation['enough']=3;
									$relation['tips'] =$result['tips'];
								}
								$next_pai =$info['next_pai'];
								$seat_list = $this->redis->hGet(self::INFO_KEY.$this->id,$seatkey);
								$seat_list =json_decode($seat_list);
								$front_list = $seat_list->front;
								$front_list[] = implode(',', $new_chi_pai);

								$present_eat =$seat_list->eat?$seat_list->eat->$throw_seatid:0;
								$seat_list->front=$front_list;

								$front_rule = $seat_list->front_rule;
								$front_rule[] = array(
										'eat'=> implode(',', $new_chi_pai),
										'pai'=>$operation['pai'],
										'throw_seatid'=>$throw_seatid,
									);
								$seat_list->front_rule = $front_rule;

								$now_throw_front = $seat_list->throw_front;
								array_pop($now_throw_front);
								$seat_list->throw_front=$now_throw_front;//删除最后一个牌

								$seat_list->$seatkey= $this->sortBy($next_pai);
								$now_present_eat = ++$present_eat;
								$seat_list->waiter_doing=array();//清空
								$seat_list->eat = array($throw_seatid=>$now_present_eat);
								$seat_list->player_action=array('eat'=>$throw_seatid);
								$upsert["$seatkey"]=  json_encode($seat_list);
								$this->redis->hMSet(self::INFO_KEY . $this->id,$upsert);
							//end
							$game_info =array($remind['seatid']=>array('type'=>array(6=>array())));
							$this->retention($game_info);
							Socket::sendToChannel("game-{$this->id}","Pushment","operation",$operation);
							Socket::sendToChannel("game-{$this->id}","Pushment","remind",$remind);
							if(is_array($relation)&&$relation){
								Socket::sendToChannel("game-{$this->id}","Pushment","relation",$relation);
							}
							
							Log::DEBUG('吃|手牌'.json_encode($next_pai)."吃牌:".json_encode($new_chi_pai)."|operation".json_encode($operation).'remind|'.json_encode($remind));
							break;
						default:
							# code...
							break;
					}

			}
			


		}
		//clear
		$all = $this->redis->hGetAll(self::PLAYER_ORDER . $this->id);
		foreach($all as $allkey=>$v){
			$this->redis->hDel(self::PLAYER_ORDER.$this->id,$allkey);
		}
		
	}
	/**
	 * 互包
	 * [hubao description]
	 * @param  [type] $seatid       [description]
	 * @param  [type] $throw_seatid [description]
	 * @return [type]               [description]
	 */
	private function hubao($seatid,$throw_seatid)
	{
		$room = $this->getInfo();
		$seatkey ="seat".$seatid;
		$seatinfo = $room[$seatkey];
		$eat = isset($seatinfo['eat'])?$seatinfo['eat']:0;
		$eat_1 = isset($eat[1])?$eat[1]:0;
		$eat_2 = isset($eat[2])?$eat[2]:0;
		$eat_3 = isset($eat[3])?$eat[3]:0;
		$eat_4 = isset($eat[4])?$eat[4]:0;
		$peng = isset($seatinfo['peng'])?$seatinfo['peng']:0;
		$peng_1 =isset($peng[1])?$peng[1]:0;
		$peng_2 =isset($peng[2])?$peng[2]:0;
		$peng_3 =isset($peng[3])?$peng[3]:0;
		$peng_4 =isset($peng[4])?$peng[4]:0;
		$gang = isset($seatinfo['gang'])?$seatinfo['gang']:0;
		$gang_1 =isset($gang[1])?$gang[1]:0;
		$gang_2 =isset($gang[2])?$gang[2]:0;
		$gang_3 =isset($gang[3])?$gang[3]:0;
		$gang_4 =isset($gang[4])?$gang[4]:0;
		$all_1 =$eat_1+$peng_1+$gang_1;
		$all_2 =$eat_2+$peng_2+$gang_2;
		$all_3 =$eat_3+$peng_3+$gang_3;
		$all_4 =$eat_4+$peng_4+$gang_4;
		$safe=array();
		for($i=1;$i<=4;$i++){
			if($i==$seatid) continue;
			if($i==1 &&$all_1>2) array_push($safe,1);
			if($i==2 &&$all_1>2) array_push($safe,2);
			if($i==3 &&$all_1>2) array_push($safe,3);
			if($i==4 &&$all_1>2) array_push($safe,4);
		}
		$theend=array();
		if(is_array($safe)&&$safe){
			foreach($safe as $next){
				$myseatkey ="seat".$next;
				$myseatinfo = $room[$myseatkey];
				$eat = isset($myseatinfo['eat'])?$myseatinfo['eat']:0;
				$eat_1 = isset($eat[1])?$eat[1]:0;
				$eat_2 = isset($eat[2])?$eat[2]:0;
				$eat_3 = isset($eat[3])?$eat[3]:0;
				$eat_4 = isset($eat[4])?$eat[4]:0;
				$peng = isset($myseatinfo['peng'])?$myseatinfo['peng']:0;
				$peng_1 =isset($peng[1])?$peng[1]:0;
				$peng_2 =isset($peng[2])?$peng[2]:0;
				$peng_3 =isset($peng[3])?$peng[3]:0;
				$peng_4 =isset($peng[4])?$peng[4]:0;
				$gang = isset($myseatinfo['gang'])?$myseatinfo['gang']:0;
				$gang_1 =isset($gang[1])?$gang[1]:0;
				$gang_2 =isset($gang[2])?$gang[2]:0;
				$gang_3 =isset($gang[3])?$gang[3]:0;
				$gang_4 =isset($gang[4])?$gang[4]:0;
				$all_1 =$eat_1+$peng_1+$gang_1;
				$all_2 =$eat_2+$peng_2+$gang_2;
				$all_3 =$eat_3+$peng_3+$gang_3;
				$all_4 =$eat_4+$peng_4+$gang_4;
				if($seatid==1 && $all_1>2) array($theend,$next);
				if($seatid==2 && $all_2>2) array($theend,$next);
				if($seatid==3 && $all_3>2) array($theend,$next);
				if($seatid==4 && $all_4>2) array($theend,$next);
			}
		}
		if(is_array($theend)&&$theend){
			if($seatid==$throw_seatid){
				return array(1=>$theend);
			}else{
				if(in_array($throw_seatid,$theend)){
					return array(2=>$theend);
				}else{
					return array(3=>$theend);
				}
			}
		}else{
			return null;
		}
	}
	/**
	 * 三包胡牌类型
	 * [sanbao description]
	 * @param  [type] $seatid       [description]
	 * @param  [type] $throw_seatid [description]
	 * @return [type]               [description]
	 */
	public function sanbao($seatid,$throw_seatid){
		$room = $this->getInfo();
		$seatkey ="seat".$seatid;
		$seatinfo = $room[$seatkey];
		$eat = isset($seatinfo['eat'])?$seatinfo['eat']:0;
		$eat_1 = isset($eat[1])?$eat[1]:0;
		$eat_2 = isset($eat[2])?$eat[2]:0;
		$eat_3 = isset($eat[3])?$eat[3]:0;
		$eat_4 = isset($eat[4])?$eat[4]:0;
		$peng = isset($seatinfo['peng'])?$seatinfo['peng']:0;
		$peng_1 =isset($peng[1])?$peng[1]:0;
		$peng_2 =isset($peng[2])?$peng[2]:0;
		$peng_3 =isset($peng[3])?$peng[3]:0;
		$peng_4 =isset($peng[4])?$peng[4]:0;
		$gang = isset($seatinfo['gang'])?$seatinfo['gang']:0;
		$gang_1 =isset($gang[1])?$gang[1]:0;
		$gang_2 =isset($gang[2])?$gang[2]:0;
		$gang_3 =isset($gang[3])?$gang[3]:0;
		$gang_4 =isset($gang[4])?$gang[4]:0;
		$all_1 =$eat_1+$peng_1+$gang_1;
		$all_2 =$eat_2+$peng_2+$gang_2;
		$all_3 =$eat_3+$peng_3+$gang_3;
		$all_4 =$eat_4+$peng_4+$gang_4;
		$over_3=array();
		if($all_1>2 && 1!=$seatid) array_push($over_3,1);
		if($all_2>2 && 2!=$seatid) array_push($over_3,2);
		if($all_3>2 && 3!=$seatid) array_push($over_3,3);
		if($all_4>2 && 4!=$seatid) array_push($over_3,4);
		if(is_array($over_3)&&$over_3){
			if($seatid==$throw_seatid){
				//自摸
				return array(1=>$over_3);
			}else{
				if(in_array($throw_seatid,$over_3)){
					return array(2=>$over_3);
				}else{
					return array(3=>$over_3);
				}
			}
		}else{
			return $over_3;
		}
		
	}
	private function getNickname($seatid){
		$seatkey='seat'.$seatid;
		$room = $this->getInfo();
		$seatinfo =$room[$seatkey];
		$uid =isset($seatinfo['uid'])?$seatinfo['uid']:0;
		$nickname="";
		if($uid){
			$mUser = new UserModel($uid);
			$info=$mUser->getUserInfoByUid();
			$nickname =isset($info['nickname'])?$info['nickname']:'';
		}
		return $nickname;
	}


	/**
	 * 是否可以杠
	 * [findPai description]
	 * @param  [type] $seat_pai [description]
	 * @param  [type] $pai      [description]
	 * @return [type]           [description]
	 */
	private function findPai($seat_pai,$pai){
		$numbers=0;
		foreach($seat_pai as $v){
			if($v==$pai){
				$numbers++;
			}
		}
		if($numbers==3){
			return true;
		}else{
			return false;
		}
	}
	private function findPengPai($seat_pai,$pai){
		$numbers=0;
		foreach($seat_pai as $v){
			if($v==$pai){
				$numbers++;
			}
		}
		if($numbers>=2){
			return true;
		}else{
			return false;
		}
	}
	/**
	 * 返回可以吃的牌
	 * [findEatPai description]
	 * @param  [type] $handscards [description]
	 * @param  [type] $pai        [description]
	 * @return [type]             [description]
	 */
	public function findEatPai($handscards,$pai){
		$pai_arr=array();
		  if($pai>=1 && $pai<=9){
			for($i=0;$i<3;$i++){
				$loop_pai = $pai-$i;
				if($loop_pai>0 && $loop_pai<8){								
					$pai2=$loop_pai+1;
					$pai3=$loop_pai+2;
					$combox=array();

					if($loop_pai!=$pai){
						array_push($combox, $loop_pai);
					}
					if($pai2!=$pai){
						array_push($combox, $pai2);
					}
					if($pai3!=$pai){
						array_push($combox, $pai3);
					}
					if(count($combox)==2){
						if(in_array($combox[0], $handscards)&& in_array($combox[1], $handscards)){
							$combox_arr =array($combox[0],$combox[1],$pai);
							sort($combox_arr);
							$pai_arr[]=$combox_arr;
						}
					}
				}
			}
		}
		//11-19
		if($pai>=11 && $pai<=19){
			for($i=0;$i<3;$i++){
				$loop_pai = $pai-$i;
				if($loop_pai>10 && $loop_pai<18){								
					$pai2=$loop_pai+1;
					$pai3=$loop_pai+2;
					$combox=array();

					if($loop_pai!=$pai){
						array_push($combox, $loop_pai);
					}
					if($pai2!=$pai){
						array_push($combox, $pai2);
					}
					if($pai3!=$pai){
						array_push($combox, $pai3);
					}
					if(count($combox)==2){
						if(in_array($combox[0], $handscards)&& in_array($combox[1], $handscards)){
							$combox_arr =array($combox[0],$combox[1],$pai);
							sort($combox_arr);
							$pai_arr[]=$combox_arr;
						}
					}
				}
			}
		}
		//21-29
		if($pai>=21 && $pai<=29){
			for($i=0;$i<3;$i++){
				$loop_pai = $pai-$i;
				if($loop_pai>20 && $loop_pai<28){								
					$pai2=$loop_pai+1;
					$pai3=$loop_pai+2;
					$combox=array();

					if($loop_pai!=$pai){
						array_push($combox, $loop_pai);
					}
					if($pai2!=$pai){
						array_push($combox, $pai2);
					}
					if($pai3!=$pai){
						array_push($combox, $pai3);
					}
					if(count($combox)==2){
						if(in_array($combox[0], $handscards)&& in_array($combox[1], $handscards)){
							$combox_arr =array($combox[0],$combox[1],$pai);
							sort($combox_arr);
							$pai_arr[]=$combox_arr;
						}
					}
				}
			}
		}
		$new_pai_arr=array();
		if(is_array($pai_arr)){
			foreach($pai_arr as $v ){
				$new_pai_arr[]=implode(',', $v);
			}
		}
		return $new_pai_arr;
	}
	private function findEat($handscards,$pai){
		if($pai>=1 && $pai<=9){
			for($i=0;$i<3;$i++){
				$loop_pai = $pai-$i;
				if($loop_pai>0 && $loop_pai<8){								
					$pai2=$loop_pai+1;
					$pai3=$loop_pai+2;
					$combox=array();

					if($loop_pai!=$pai){
						array_push($combox, $loop_pai);
					}
					if($pai2!=$pai){
						array_push($combox, $pai2);
					}
					if($pai3!=$pai){
						array_push($combox, $pai3);
					}
					if(count($combox)==2){
						if(in_array($combox[0], $handscards)&& in_array($combox[1], $handscards)){
							return true;
						}
					}
				}
			}
		}
		//11-19
		if($pai>=11 && $pai<=19){
			for($i=0;$i<3;$i++){
				$loop_pai = $pai-$i;
				if($loop_pai>10 && $loop_pai<18){								
					$pai2=$loop_pai+1;
					$pai3=$loop_pai+2;
					$combox=array();

					if($loop_pai!=$pai){
						array_push($combox, $loop_pai);
					}
					if($pai2!=$pai){
						array_push($combox, $pai2);
					}
					if($pai3!=$pai){
						array_push($combox, $pai3);
					}
					if(count($combox)==2){
						if(in_array($combox[0], $handscards)&& in_array($combox[1], $handscards)){
							return true;
						}
					}
				}
			}
		}
		//21-29
		if($pai>=21 && $pai<=29){
			for($i=0;$i<3;$i++){
				$loop_pai = $pai-$i;
				if($loop_pai>20 && $loop_pai<28){								
					$pai2=$loop_pai+1;
					$pai3=$loop_pai+2;
					$combox=array();

					if($loop_pai!=$pai){
						array_push($combox, $loop_pai);
					}
					if($pai2!=$pai){
						array_push($combox, $pai2);
					}
					if($pai3!=$pai){
						array_push($combox, $pai3);
					}
					if(count($combox)==2){
						if(in_array($combox[0], $handscards)&& in_array($combox[1], $handscards)){
							return true;
						}
					}
				}
			}
		}
		return false;
	}
	public function changeFrontPai($frontpai){
		$new_front_pai =array();
		if(is_array($frontpai)&&$frontpai){
			foreach ($frontpai as $key => $value) {				
				$out_front_api= explode(',', $value);
				$new_front_pai=array_merge($new_front_pai,$out_front_api);
			}
		}
		return $new_front_pai;
	}
	/**
	 * 算分
	 * [sumscore description]
	 * @param  [type] $allpai   [description]  所有牌 不包含花
	 * @param  [type] $handpai  [description]  剩余手牌
	 * @param  [type] $frontpai [description]  吃 碰 杠 的牌
	 * @param  [type] $flowerpai [description]  花牌
	 * @return [type]           [description]
	 */
	public function sumscore($seatid,$pai=null,$throw_seatid=4,$satisfy_ok=array()){
		// $request=$this->redis->GET(self::SUM.$this->id.$seatid);
		// if($request) return;

		// $this->redis->SET(self::SUM.$this->id.$seatid,1);
		//$allpai,$handpai,$frontpai,$flowerpai
		$user = $this->mUser->getInfo();
		$info = $this->getInfo();
		//切换庄家和牌局重置
		//$double =$info['double'];//倍数 1
		// $banker =$info['banker'];//当前庄家
		// if($banker!=$user['seatid']){
		// 	$dachu['banker']= $user['seatid'];
		// 	$this->redis->hMSet(self::INFO_KEY . $this->id,$dachu);
		// }
		$seatkey ="seat".$seatid;
		$myseatInfo =$info[$seatkey];//我的牌信息
		
		$present_quan =$info['present_quan'];//目前圈
		$handpai =$myseatInfo[$seatkey];
		Log::DEBUG("sumscore".json_encode($handpai));
		$throw_front=isset($myseatInfo['throw_front'])?$myseatInfo['throw_front']:'';//我仍出的牌

		$throwkey="seat".$throw_seatid;
		$throwInfo =$info[$throwkey];
		$banker_throw_front=isset($throwInfo['throw_front'])?$throwInfo['throw_front']:'';//打出的牌
		$player_action =isset($throwInfo['player_action'])?$throwInfo['player_action']:'';
		$gangInfo="";
		if($player_action){
			$gangInfo=isset($player_action['gang'])?$player_action['gang']:'';
		}
		$allpai =$pai?array_merge($handpai,array($pai)):$handpai;//所有牌包括抓取的

		$allpai=$this->clearFlower($allpai);
		$handpai =$this->clearFlower($handpai);
		$handpai =$this->sortBy($handpai);

		Log::DEBUG('计算手牌'.json_encode($handpai));
		Log::DEBUG('计算单独牌'.json_encode($pai));
		//$handpai= array(9,9,21,21);
		$flowerpai = isset($myseatInfo['get_flower'])?$myseatInfo['get_flower']:'';


		$frontpai =isset($myseatInfo['front'])?$myseatInfo['front']:'';//吃 碰 杠
		$frontpai =$this->changeFrontPai($frontpai);
		Log::DEBUG('计算台面牌'.json_encode($frontpai));
		// $handpai= array(16,16,16,18,18,23,24);
		// $frontpai=array(15,15,15,27,27,27);

		$frontpai =$this->sortBy($frontpai);
		//$front_pai =array(2,3,4,17,17,17,27,28,29);
		Log::DEBUG('座位'.$seatid.' 仍座位'.$throw_seatid.'手牌'.json_encode($handpai).'台面'.json_encode($frontpai).'单独牌'.'花'.json_encode($flowerpai));
		if(!$handpai||!$frontpai||!$pai) return false;
		$eat =isset($myseatInfo['eat'])?$myseatInfo['eat']:'';
		if(is_array($eat)&&$eat){
			foreach ($eat as $value) {
				$eat_total+=$value;
			}
		}
		$peng =isset($myseatInfo['peng'])?$myseatInfo['peng']:'';
		if(is_array($peng)&&$peng){
			foreach ($peng as $value) {
				$peng_total+=$value;
			}
		}
		$gang =isset($myseatInfo['gang'])?$myseatInfo['gang']:'';
		if(is_array($gang)&&$gang){
			foreach ($gang as $value) {
				$gang_total+=$value;
			}
		}
		//$peng="";
		//print_r($allpai);exit;
		//牌型ABC ABC ABC ABC AA 。没有碰过,AA不能是有台数风牌 1台
		//$satisfy_ok = array();
		//8花胡
		//$satisfy_ok =array();
		if(count($flowerpai)==8){
			array_push($satisfy_ok,18);
		}
		//4花
		if(count($flowerpai)==4){
			$oba =array(41,42,43,44);
			$obb =array(45,46,47,48);
			$before=true;
			$after= true;
			foreach($flowerpai as $aflowerpai){
				if(!in_array($aflowerpai,$oba)){
					$before= false;
				}
				if(!in_array($aflowerpai,$obb)){
					$after= false;
				}
			}
			if($before||$after){
				array_push($satisfy_ok, 19);
			}
		}

		$myhandpai_counts=count($allpai);
		if($myhandpai_counts==14){
			//十三幺
			if($this->isShisanyao($allpai)){
				array_push($satisfy_ok,27);
			}
		}
		//平胡
		if($this->isPinghu($allpai) && !$peng){
			array_push($satisfy_ok, 1);
		}
		//边胡
		$pai=$this->clearFlower($pai);
		$pai =isset($pai[0])?$pai[0]:$pai;
		$this->findBianHu($pai,$handpai,$frontpai,$satisfy_ok);
		$this->findDuidao($pai,$handpai,$satisfy_ok);
		//手上只有一张牌的时候
		if(count($handpai)==1 && is_array($handpai)){
			array_push($satisfy_ok, 7);
		}
		//对对胡
		$this->findDuiDuiHu($pai,$handpai,$frontpai,$satisfy_ok);
		$this_seatid =$user['seatid'];
		if($gangInfo && $user['seatid']!=$gangInfo){
			array_push($satisfy_ok, 11);//拉杠
		}
		//门清
		if(empty($frontpai)){
			array_push($satisfy_ok, 25);
		}
		if(is_array($banker_throw_front) && count($banker_throw_front)==1 && !$throw_front){
			//地胡
			array_push($satisfy_ok, 13);
		}
		$tag=$this->qingyise($pai,$handpai,$frontpai);
		if($tag==2){
			array_push($satisfy_ok, 14);
		}
		$this->hunyise($pai,$handpai,$frontpai,$satisfy_ok);
		$this->ziyise($pai,$handpai,$frontpai,$satisfy_ok);
		$this->dasanyuan($pai,$handpai,$frontpai,$satisfy_ok);
		$taishu =$this->zhongfabai($pai,$handpai,$frontpai);
		$this->zhengfeng($pai,$handpai,$frontpai,$seatid,$banker,$satisfy_ok);
		$this->quanfeng($pai,$handpai,$frontpai,$present_quan,$satisfy_ok);
		Log::DEBUG('花牌计算'.json_encode($flowerpai));	
		$zheng_yehua = $this->zhenghuayehua($flowerpai,$seatid,$satisfy_ok);
		//西周麻将
		if($info['game_type']=='xizhou'){
			$this->bangao($pai,$handpai,$frontpai,$satisfy_ok);
			$this->tuobangao($pai,$handpai,$satisfy_ok);
			// 板高     牌型ABC+ABC或AABBCC      6台
			// 双板高     牌型ABC+ABC+DEF+DEF或AABBCC+DDEEFF     15台
			// 托板高     牌型ABC+ABC+ABC或AAABBBCCC（不能为碰出的）     25台
			// 断幺     牌型内无1、9、风牌、中发白     1台
		}
		$type =$info['game_type']=="xizhou"?2:1;
		Log::DEBUG('满足的数字：'.json_encode($satisfy_ok));		
		if(is_array($satisfy_ok)&&$satisfy_ok){
			$str=implode(",", $satisfy_ok);
		}
		$config_obj=Yaf_Registry::get("config");
		$config_database =$config_obj->database->config->toArray();
		$prefix =$config_database['prefix'];

		$rulesTable = new HbModel($prefix.'majiang_rules');			
		$options['where']=array('type'=>$type ,'pos'=>array('IN', $str));
		$dblist = $rulesTable->select($options);
		$aList =array(); 
		$all_taishu=0;
		//zhenghua
		Log::DEBUG('正花野花.'.json_encode($zheng_yehua));
		if($zheng_yehua['zhenghua']){
			$condition['where']= array('type'=>$type ,'pos'=>24);
			$hualist = $rulesTable->select($condition);
			if(is_array($hualist)&&$hualist){
				foreach($hualist as $v){
					$db_zhenghua=$v['score'];
					$aList[]=array('title'=>$v['title'],'score'=>$v['score']);
				}
			}
			$all_taishu = $zheng_yehua['zhenghua']*$db_zhenghua;
		}
		//yehua
		if($zheng_yehua['yehua']){
			$condition['where']= array('type'=>$type ,'pos'=>26);
			$hualist = $rulesTable->select($condition);
			if(is_array($hualist)&&$hualist){
				foreach($hualist as $v){
					$db_yehua=$v['score'];
					$aList[]=array('title'=>$v['title'],'score'=>$v['score']);
				}
			}
			$all_taishu += $zheng_yehua['yehua']*$db_yehua;
		}
		if(is_array($dblist)&&$dblist){
			foreach($dblist as $v){
				$all_taishu+=$v['score'];
				$aList[]=array('title'=>$v['title'],'score'=>$v['score']);
			}
		}
		if($taishu){
			array_push($aList,array('title'=>'中发白','score'=>$taishu));	
		}
		$all_taishu+=$taishu;
		// $this->redis->del(self::SUM.$this->id,$seatid);
		return array(
				'all_taishu'=>$all_taishu,
				'aList'=>$aList,
			);
	}
	private function tuobangao($pai,$handpai,& $satisfy_ok){
			$handpai =array_merge($handpai,array($pai));
			$handpai =$this->sortBy($handpai);
			$this->filterduiduiShunzi($handpai,$pai,$times,$times_sec);
			if($times_sec>=1){
				array_push($satisfy_ok,30);
			}
	}
	private function bangao($pai,$handpai,$frontpai,& $satisfy_ok){
			$handpai =array_merge($handpai,$frontpai);
			$handpai =array_merge($handpai,array($pai));
			$handpai =$this->sortBy($handpai);
			$handscards = $this->filterduiduiShunzi($handpai,$pai,$times,$times_sec);
			if($times==1){
				array_push($satisfy_ok,28);
			}elseif($times==2){
				array_push($satisfy_ok,29);
			}
			
	}
	private  function zhenghuayehua($flowerpai,$seatid,& $satisfy_ok)
	{
		$flower_arr =array( 
					'1'=>array(
							41,
							45,
						),
					'2'=>array(
							42,
							46,
						),
					'3'=>array(
							43,
							47,
						),
					'4'=>array(
							44,
							48,
						),
				);
		$flower = $flower_arr[$seatid];
		$numbers=0;
		$yehua=0;
		if(is_array($flowerpai)&&$flowerpai){
			foreach ($flowerpai as $key => $value) {
				if(in_array($value,$flower)){
					$numbers++;
				}else{
					$yehua++;
				}
			}
		}
		return array('zhenghua'=>$numbers,'yehua'=>$yehua);
		// if($numbers==2){
		// 	array_push($satisfy_ok, 24);
		// }
		// if($yehua>=2){
		// 	array_push($satisfy_ok, 26);
		// }
	}
	private function quanfeng($pai,$handpai,$frontpai,$present_quan,& $satisfy_ok){
		$feng_arr =array('1'=>31,'2'=>32,'3'=>33,'4'=>34);
		$needpai =$feng_arr[$present_quan];
		$static_list =$this->commonDouble($frontpai);
		if(is_array($static_list)&& $static_list){
		 	foreach($static_list as $keys=>$next){
		 		if($next>=3){
		 			if($frontpai[$keys]==$needpai){
		 				array_push($satisfy_ok, 23);
		 				break;
		 			}
		 		}
			}
		}
	}
	private  function zhengfeng($pai,$handpai,$frontpai,$seatid,$banker,& $satisfy_ok)
	{
		//$feng_arr =array('1'=>31,'2'=>32,'3'=>33,'4'=>34);
		$banker= $banker?$banker:1;
		$dong =$banker;
		$nan= $dong==4?1:$dong+1;
		$xi= $nan==4?1:$nan+1;
		$bei =$xi==4?1:$xi+1;
		$feng_arr = array($dong=>31,$nan=>32,$xi=>33,$bei=>34);
		$needpai =$feng_arr[$seatid];
		$static_list =$this->commonDouble($frontpai);
		if(is_array($static_list)&& $static_list){
		 	foreach($static_list as $keys=>$next){
		 		if($next>=3){
		 			if($frontpai[$keys]==$needpai){
		 				array_push($satisfy_ok, 22);
		 				break;
		 			}
		 		}
			}
		}
	}
	private function zhongfabai($pai,$handpai,$frontpai){
		//有几个就是几台
		$allpai =$frontpai;
		$allpai =$this->sortBy($allpai);
		$static_list =$this->commonDouble($allpai);
		$zhongfabai =array();
		if(is_array($static_list)&& $static_list){
		 	foreach($static_list as $keys=>$next){
		 		if($next>=3){
		 			if($allpai[$keys]>=35 && $allpai[$keys]<=37){
		 				array_push($zhongfabai, $allpai[$keys]);
		 			}
		 		}
		 	}
		}
		return count($zhongfabai);
	}
	private function dasanyuan($pai,$handpai,$frontpai,& $satisfy_ok){
		//大三元 在手牌里
		$allpai =array_merge(array($pai),$handpai);
		//$allpai =array_merge($allpai,$frontpai);
		$allpai =$this->sortBy($allpai);
		$static_list =$this->commonDouble($allpai);
		$zhongfabai =array();
		if(is_array($static_list)&& $static_list){
		 	foreach($static_list as $keys=>$next){
		 		if($next>=3){
		 			if($allpai[$keys]>=35 && $allpai[$keys]<=37){
		 				array_push($zhongfabai, $allpai[$keys]);
		 			}
		 		}
		 	}
		}
		$pipeizhongfabai =array(35,36,37);
		if(is_array($zhongfabai)&&$zhongfabai){
			$a=implode(',',$pipeizhongfabai);
			$b =implode(',', $zhongfabai);
			if($a==$b){
				array_push($satisfy_ok,20);
			}
		}


	}
	private function ziyise($pai,$handpai,$frontpai,& $satisfy_ok){
		$allpai =array_merge(array($pai),$handpai);
		$allpai =array_merge($allpai,$frontpai);
		$allpai =$this->sortBy($allpai);
		$iszipai=true;
		$allpai=$this->clearFlower($allpai);
		if(is_array($allpai)&&$allpai){
			foreach ($allpai as $key => $value) {
				if($value<31){
					$iszipai=false;
					break;
				}
			}
		}
		if($iszipai){
			array_push($satisfy_ok, 16);
		}
	}
	private function hunyise($pai,$handpai,$frontpai,& $satisfy_ok){
		//去除字牌
		$allpai =array_merge(array($pai),$handpai);
		$allpai =array_merge($allpai,$frontpai);
		$allpai =$this->sortBy($allpai);
		//清除35-37
		//是否有字牌
		$zipai=array();
		if(is_array($allpai)&&$allpai){
			foreach ($allpai as $key => $value) {
				if($value>=31&& $value<=37){
					$zipai =true;
					unset($allpai[$key]);//碰 杠
				}
			}
		}
		if(!$zipai){
			return false;
		}
		$allpai =array_merge(array(),$allpai);
		$tag=$this->qingyise($pai,$allpai,array());
		if($tag==2){
			array_push($satisfy_ok, 15);
		}
	}
	private function qingyise($pai,$handpai,$frontpai){
		$type =1;//1-9
		if($pai>=11&&$pai<=19){
			$type=2;
		}elseif($pai>=21 &&$pai<=29){
			$type=3;
		}else{

		}
		$combox =array_merge($frontpai,$handpai);
		if(is_array($combox)&&$combox){
			foreach($combox as $next){
				$tag =1;
				switch ($type) {
					case 1:
						if($next>=1&& $next<=9){
							$tag=2;
						}
						break;
					case 2:
						if($next>=11&& $next<=19){
							$tag=2;
						}
						break;
					case 3:
						if($next>=21&& $next<=29){
							$tag=2;
						}
						break;
					default:
						# code...
						break;
				}
				if($tag==1) break;
			}
		}
		return $tag;
	}
	private function findDuiDuiHu($pai,$handscards,$frontpai,& $satisfy_ok){
		$next_front_count ='';
		$prev_front_count ='';
		if(is_array($frontpai)&&$frontpai){
			$prev_front_count = count($frontpai);
			$frontpai =$this->filterShunzi($frontpai);
			$frontpai =$this->filterduiduiShunzi($frontpai,$pai,$times,$times_sec);
			$next_front_count =count($frontpai);
		}

		//吃碰杠 台面牌
		$handscards =array_merge(array($pai),$handscards);
		$handscards = $this->sortBy($handscards);
		$prev_count = count($handscards);
		$handscards =$this->filterShunzi($handscards);	
		$handscards =$this->filterduiduiShunzi($handscards,$pai,$times,$times_sec);
		$next_count =count($handscards);
		if($next_count==$prev_count && $prev_front_count==$next_front_count){
			array_push($satisfy_ok, 8);
		}
	}
	private function findDuidao($pai,$handpai,& $satisfy_ok){
		$handpai =array_merge(array($pai),$handpai);
		$handscards =$this->sortBy($handpai);
		$handscards=$this->filterShunzi($handscards);
		$total=count($handscards);
		for ($i=0; $i < $total; $i++) {
			for ($j=$i+1; $j <$total; $j++) { 
				if($handscards[$i]==$handscards[$j]){
					if(isset($arr_nums[$i])){
						$arr_nums[$i]+=1;
					}else{
						if( (!isset($arr_nums[$i-1]) && !isset($arr_nums[$i-2])) || (isset($arr_nums[$i-2]) && $arr_nums[$i-2]==2) ){
							$arr_nums[$i]=2;
						}
						
					}
				}
			}
		}
		$quantity=0;
		$duizi=array();
		if(is_array($arr_nums)&&$arr_nums){
			foreach($arr_nums as $key=>$v){				
				if($v>2) continue;
				//抓的牌正好是一对的
				if($v==2){
					array_push($duizi,$handscards[$key]);
					$quantity++;
				}
			}
			if($quantity==2 && in_array($pai,$duizi)){
				array_push($satisfy_ok, 3);
				return true;
			}
			

		}else{
			return false;
		}
	}
	private function findBianHu($pai,$handpai,$frontpai,& $satisfy_ok){
		 //$handpai =array_merge($handpai,array($pai));
		 $handpai =$this->sortBy($handpai);
		 $handscards =$this->filterShunzi($handpai);

		 $handscards =$this->filterduiduiShunzi($handscards,$pai,$times,$times_sec);
		 //把三张 4 2张的全部去了
		 $static_list = $this->commonDouble($handscards);
		 if(is_array($static_list)&& $static_list){
		 	foreach($static_list as $keys=>$next){
		 		if($next>1){
		 			for($j=0;$j<$next;$j++){
		 				$new_keys =$keys+$j*1;
		 				unset($handscards[$new_keys]);
		 			}
		 		}
		 	}
		 }
		 $left_count =count($handscards);
		 $condition=array(
		 		0=>array(1,2),
		 		1=>array(8,9),
		 		2=>array(11,12),
		 		3=>array(18,19),
		 		4=>array(21,22),
		 		5=>array(28,29),
		 	);
		 $handscards =array_merge(array(),$handscards);
		if($left_count==2 && $handscards[0]!=$handscards[1]){
		 	foreach ($condition as $key => $value) {
		 		if(in_array($handscards[0], $value)&& in_array($handscards[1], $value)){
		 			array_push($satisfy_ok, 2);
		 		}
		 	}
		 	//是否嵌倒
		 	if($handscards[1]-$handscards[0]==2){
		 		array_push($satisfy_ok, 4);
		 	}

		 }elseif($left_count==1){
		 	if($handscards[0]==$pai){
		 		//单吊 有三张一样的
		 		$isHaslgt =false;
		 		foreach($static_list as $v){
		 			if($v>2){
		 				$isHaslgt=true;
		 			}
		 		}
		 		if(!$isHaslgt){
		 			//查找吃碰杠里
		 			$arr_list = $this->commonDouble($frontpai);
		 			if(count($arr_list)){
		 				foreach($arr_list as $next){
		 					if($next>2){
		 						$isHaslgt=true;
		 					}
		 				}
		 			}

		 		}
		 		//if($isHaslgt){
		 			array_push($satisfy_ok, 5);
		 		//}
		 		
		 	}
		 }
	}
	private function commonDouble($handscards){
		$total =count($handscards);
		$arr_nums =array();
		for ($i=0; $i < $total; $i++) {
			for ($j=$i+1; $j <$total; $j++) { 
				if($handscards[$i]==$handscards[$j]){
					if(isset($arr_nums[$i])){
						$arr_nums[$i]+=1;
					}else{
						if( (!isset($arr_nums[$i-1]) && !isset($arr_nums[$i-2])) || (isset($arr_nums[$i-2]) && $arr_nums[$i-2]==2) ){
							$arr_nums[$i]=2;
						}
						
					}
				}
			}
		}
		return $arr_nums;
	}
	private function filterduiduiShunzi($handscards,$pai,& $times,& $times_sec){
		$total =count($handscards);
		for ($i=0; $i < $total; $i++) {
			for ($j=$i+1; $j <$total; $j++) { 
				if($handscards[$i]==$handscards[$j]){
					if(isset($arr_nums[$i])){
						$arr_nums[$i]+=1;
					}else{
						if( (!isset($arr_nums[$i-1]) && !isset($arr_nums[$i-2])) || (isset($arr_nums[$i-2]) && $arr_nums[$i-2]==2) ){
							$arr_nums[$i]=2;
						}
						
					}
				}
			}
		}
		$double_pai =array();
		$special_pai=array();
		$three_special=array();
		if(is_array($arr_nums)&&$arr_nums){
			foreach($arr_nums as $key => $value) {
				if($value==2) array_push($double_pai, $key);
				//if($value==2) array_push($special_pai, $key);
				if($value==3) array_push($three_special, $key);
			}
		}
		$before_count= count($handscards);
		for($i=0;$i<count($double_pai)-2;$i++){
			if(isset($handscards[$double_pai[$i]])&&$handscards[$double_pai[$i]]!=$pai && $handscards[$double_pai[$i]]+1==$handscards[$double_pai[$i+1]] && $handscards[$double_pai[$i]]+2==$handscards[$double_pai[$i+2]]){
				unset($handscards[$double_pai[$i]]);
				unset($handscards[$double_pai[$i]+1]);		
				unset($handscards[$double_pai[$i+1]]);				
				unset($handscards[$double_pai[$i+1]+1]);				
				unset($handscards[$double_pai[$i+2]]);				
				unset($handscards[$double_pai[$i+2]+1]);				
				//break;				
				$times++;
			}
		}
		$after_count=count($handscards);
		if($after_count==$before_count){
			for($i=0;$i<count($special_pai)-2;$i++){
				if( $handscards[$special_pai[$i]]+1==$handscards[$special_pai[$i+1]] && $handscards[$special_pai[$i]]+2==$handscards[$special_pai[$i+2]]){
					unset($handscards[$special_pai[$i]]);
					unset($handscards[$special_pai[$i]+1]);		
					unset($handscards[$special_pai[$i+1]]);				
					unset($handscards[$special_pai[$i+1]+1]);				
					unset($handscards[$special_pai[$i+2]]);				
					unset($handscards[$special_pai[$i+2]+1]);				
					break;
				}
			}
		}
		$now_count =count($handscards);
		if($now_count==$after_count){
			for($i=0;$i<count($three_special)-2;$i++){
				if( $handscards[$three_special[$i]]+1==$handscards[$three_special[$i+1]] && $handscards[$three_special[$i]]+2==$handscards[$three_special[$i+2]] ){
					unset($handscards[$three_special[$i]]);
					unset($handscards[$three_special[$i]+1]);
					unset($handscards[$three_special[$i]+2]);

					unset($handscards[$three_special[$i+1]]);				
					unset($handscards[$three_special[$i+1]+1]);	
					unset($handscards[$three_special[$i+1]+2]);	

					unset($handscards[$three_special[$i+2]]);				
					unset($handscards[$three_special[$i+2]+1]);
					unset($handscards[$three_special[$i+2]+2]);
					$times_sec++;
					break;
				}
			}
		}

		$handscards =array_merge(array(),$handscards);
		return $handscards;
	}
	//平胡
	private function isPinghu($pai){
		$handscards =$this->sortBy($pai);
		$total=count($handscards);
		for ($i=0; $i < $total; $i++) {
			for ($j=$i+1; $j <$total; $j++) { 
				if($handscards[$i]==$handscards[$j]){
					if(isset($arr_nums[$i])){
						$arr_nums[$i]+=1;
					}else{
						if( (!isset($arr_nums[$i-1]) && !isset($arr_nums[$i-2])) || (isset($arr_nums[$i-2]) && $arr_nums[$i-2]==2) ){
							$arr_nums[$i]=2;
						}
						
					}
				}
			}
		}
		$samepai =count($arr_nums);
		if(!$samepai){
			return false;
		}
		$isPingHu=true;
		foreach($arr_nums as $key=>$value){
			if($value>2){
				$isPingHu=false;
				break;
			}
		}
		if(!$isPingHu){
			return false;
		}
		$new_double_pai =array();
		$this_cards =$handscards;
		foreach($arr_nums as $key=>$vv){
			$double_pai= $this_cards[$key];

			array_push($new_double_pai, $double_pai);
			unset($this_cards[$key]);
			unset($this_cards[$key+1]);
		}
		//把对顺子去了
		$numbers= count($new_double_pai);
		if($numbers>1 && ($numbers-1)%3==0){
			for($i=0;$i<$numbers;$i++){
				for($j=$i+1;$j<$numbers-1;$j++){
					if($new_double_pai[$i]+1==$new_double_pai[$j] && $new_double_pai[$i]+2==$new_double_pai[$j+1]){
						unset($new_double_pai[$i]);
						unset($new_double_pai[$i+1]);
						unset($new_double_pai[$i+2]);
						break;
					}
				}				
			}
		}
		if(count($new_double_pai)==1){
			$cur_pai= $new_double_pai[0];
			if($cur_pai>=31 &&$cur_pai<=34){
				return false;
			}		
		}
		if($this->checkShunzi($this_cards)){
			return true;
		}else{
			return false;
		}
		
	}
	private function checkShunzi($this_cards){	
		$this_cards = array_merge(array(),$this_cards);
		$left_count = count($this_cards);
		if(!$left_count) return true;
		if($left_count%3!=0) return false;
		for($i=0;$i<$left_count-2;$i++){
			if($this_cards[$i]==$this_cards[$i+1]-1 && $this_cards[$i]==$this_cards[$i+2]-2){
				array_shift($this_cards);
				array_shift($this_cards);
				array_shift($this_cards);				
				return $this->checkShunzi($this_cards);
			}
		}
	}
}